import React from 'react';
import * as _ from 'lodash';
import { Checkbox } from 'antd';
import List from '../SimpleList';
import IconFont from '../../../themeComponents/IconFont';
import { isEqual } from '@zenview/micro-utils';
import CBox from '../../../themeComponents/CBox';
import TreeTitle from '../../../businessComponents/TreeTitle';
import { lineItemNormal } from './renderItem';
import './index.less';

class CheckList extends React.Component {
  static defaultProps = {
    itemKey: 'id',
    itemNameKey: 'name',
  };
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
    const { checkedKeys, defaultCheckedIds, itemKey, list } = this.props;
    const { checkHalfStatus, checkAllStatus } = this.computedCheckStatus(list, checkedKeys, itemKey);
    this.state = {
      isCheckedChange: false,
      isForceUpdate: false,
      activeKey: props.activeKey,
      keywords: props.keywords,
      checkHalfStatus,
      checkAllStatus,
      checkedKeys: _.cloneDeep(defaultCheckedIds) || _.cloneDeep(checkedKeys) || undefined,
    };
  }
  static getDerivedStateFromProps(props, state) {
    const options = {};
    if (props.checkable && !props.checkedKeys && !state.checkedKeys && Array.isArray(props.defaultCheckedIds)) {
      options.checkedKeys = _.cloneDeep(props.defaultCheckedIds);
      options.isCheckedChange = true;
      options.isForceUpdate = true;
    }
    if (props.checkable && props.checkedKeys && !isEqual(props.checkedKeys, state.checkedKeys)) {
      options.checkedKeys = _.cloneDeep(props.checkedKeys);
      options.isCheckedChange = true;
      options.isForceUpdate = true;
    }
    if (props.keywords !== undefined && props.keywords !== state.keywords) {
      options.keywords = props.keywords;
      options.isForceUpdate = true;
      options.isCheckedChange = true;
    }
    if (props.activeKey && props.activeKey !== state.activeKey) {
      options.activeKey = props.activeKey;
      options.isForceUpdate = true;
    }
    if (!_.isEmpty(options)) {
      return options;
    }
    return null;
  }

  componentDidUpdate() {
    if (this.state.isCheckedChange) {
      const { checkedKeys } = this.state;
      const { list, itemKey } = this.props;
      const { checkHalfStatus, checkAllStatus } = this.computedCheckStatus(list, checkedKeys, itemKey);
      this.setState({
        isCheckedChange: false,
        checkHalfStatus,
        checkAllStatus,
      });
    }
    if (this.state.isForceUpdate) {
      this.setState({ isForceUpdate: false });
      this.listRef && this.listRef.current && this.listRef.current.forceUpdateGrid();
    }
  }

  componentWillUnmount() {
    this.listRef = null;
  }

  // 计算全选半选状态
  computedCheckStatus = (list = [], checkedKeys = [], key = 'id') => {
    const listKey = list.map((v) => v[key]);
    const temp = _.intersectionBy(listKey, checkedKeys);
    const checkHalfStatus = temp.length && temp.length < list.length;
    const checkAllStatus = list.length && temp.length === list.length;
    return {
      checkHalfStatus,
      checkAllStatus,
      listKey,
    };
  };

  /**
   * @计算选中id集合
   */
  onChecked = async (e) => {
    let ids = this.state.checkedKeys || [];
    const id = e.target.value;
    const flag = e.target.checked;
    if (flag) {
      ids.push(id);
    } else {
      ids = ids.filter((v) => v !== id);
    }
    return await this.checkChange(ids);
  };

  /**
   * @修改选中状态
   */
  checkChange = async (ids) => {
    const { list, itemKey } = this.props;
    const { checkHalfStatus, checkAllStatus, listKey } = this.computedCheckStatus(list, ids, itemKey);
    await this.setState({ checkedKeys: ids, checkHalfStatus, checkAllStatus });
    this.props.onChecked && this.props.onChecked(ids, _.difference(listKey, ids));
    this.listRef && this.listRef.current && this.listRef.current.forceUpdateGrid();
  };

  // 渲染列表项
  rowRender = ({ key, index, style }) => {
    const { customRender } = this.props;
    if (customRender) {
      return customRender(this.props, this.state, this.onChecked, { key, index, style });
    }
    return lineItemNormal(this.props, this.state, this.onChecked, { key, index, style });
  };

  render() {
    let {
      className = '',
      title = '摄像机列表',
      checkableTitle = '全选',
      checkNum = false,
      checkExt = null,
      list = [], // 列表数据
      checkable = true, // 是否显示checkbox
      placeholder = '请输入设备名称搜索',
      onChange,
      itemKey = 'id',
      hasHeader = true,
      style,
      destoryList,
    } = this.props;
    list = this.props.list.map((v) => ({ title: v.deviceName, key: v.id, ...v }));

    let { checkHalfStatus, checkAllStatus, checkedKeys } = this.state;

    return (
      <CBox className={`lm-c-check-list-wrapper ${className}`} style={style}>
        {hasHeader && <TreeTitle title={title} hasInput={!!onChange} onChange={onChange} inputPlaceholder={placeholder} />}
        {(checkable || destoryList || checkExt) && (
          <div className="list-checkall">
            {checkable && (
              <Checkbox
                indeterminate={checkHalfStatus}
                checked={checkAllStatus}
                onChange={() =>
                  this.checkChange(
                    checkAllStatus
                      ? _.difference(
                          checkedKeys,
                          list.map((v) => v[itemKey])
                        )
                      : _.uniq(
                          [].concat(
                            checkedKeys,
                            list.map((v) => v[itemKey])
                          )
                        )
                  )
                }
                disabled={!list.length}
              >
                {checkableTitle}
                {checkNum && (
                  <>
                    (已选 <span style={{ color: '#fd9838' }}>{checkedKeys.length}</span> / 总数 <span style={{ color: '#fd9838' }}>{list.length}</span>)
                  </>
                )}
              </Checkbox>
            )}
            {destoryList && <IconFont type="icon-S_AID_delete" onClick={destoryList} />}
            {checkExt}
          </div>
        )}

        <div className="lm-c-base-list-layout">
          <List className="lm-c-virtual-layout" data={list} rowHeight={30} rowRenderer={this.rowRender} ref={this.listRef} />
        </div>
      </CBox>
    );
  }
}

export default CheckList;
