import React from 'react';
import List from '../SimpleList';
import ListNonVir from '../ListNonVir';
import { cloneDeep, isEmpty, intersectionBy, difference, uniq } from 'lodash';
import { Checkbox } from 'antd';
import IconFont from '../../../themeComponents/IconFont';
import CBox from '../../../themeComponents/CBox';
import { isEqual } from '@zenview/micro-utils';
import { lineItemHasDnd, lineItemNormal } from './renderItem';
import TreeTitle from '../../../businessComponents/TreeTitle';

import './index.less';

export default class BaseList 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, item }) => {
    const { needDnd } = this.props;
    return !needDnd ? lineItemNormal(this.props, this.state, this.onChecked, { key, index, style }) : lineItemHasDnd(this.props, this.state, this.onChecked, { item }, this.dragEnd, this.dragStart);
  };

  // ----------------------------------------------拖拽---begin------------------------------
  dragStart = (e) => {
    this.dragged = e.currentTarget;
  };
  dragEnd = (e) => {
    const { list } = this.props;
    let listTemp = cloneDeep(list);
    this.dragged.style.display = 'block';
    e.target.classList.remove('drag-up');
    this.over.classList.remove('drag-up');
    e.target.classList.remove('drag-down');
    this.over.classList.remove('drag-down');
    var from = Number(this.dragged.dataset.id);
    var to = Number(this.over.dataset.id);
    listTemp.splice(to, 0, listTemp.splice(from, 1)[0]);
    listTemp = listTemp.map((doc, index) => {
      doc.newIndex = index + 1;
      return doc;
    });
    this.props.dragOrders(listTemp);
  };

  dragOver = (e) => {
    e.preventDefault();
    this.dragged.style.display = 'none';
    if (e.target.parentElement.parentElement.getAttribute('class') && e.target.parentElement.parentElement.getAttribute('class').trim() === 'list-item') {
      let destTarget = e.target.parentElement.parentElement;
      const dgIndex = JSON.parse(this.dragged.dataset.item).newIndex;
      const taIndex = JSON.parse(destTarget.dataset.item).newIndex;
      const animateName = dgIndex > taIndex ? 'drag-up' : 'drag-down';
      if (this.over && destTarget.dataset.item !== this.over.dataset.item) {
        this.over.classList.remove('drag-up', 'drag-down');
      }

      if (!destTarget.classList.contains(animateName)) {
        destTarget.classList.add(animateName);
        this.over = destTarget;
      }
    }
  };
  // ----------------------------------------------拖拽---end------------------------------

  typeSelect = (type, list, e) => {
    console.log(e);
    this.setState({ buttomType: 'primary' });
  };

  render() {
    const {
      className = '',
      title = '摄像机列表',
      checkableTitle = '全选',
      list = [], // 列表数据
      checkable = true, // 是否显示checkbox
      placeholder = '请输入设备名称搜索',
      onChange,
      itemKey = 'id',
      hasHeader = true,
      destoryList,
      needDnd,
    } = this.props;
    const { checkHalfStatus, checkAllStatus, checkedKeys } = this.state;

    return (
      <CBox className={`lm-c-base-list-wrapper ${className}`}>
        {hasHeader && <TreeTitle title={title} hasInput={!!onChange} onChange={onChange} inputPlaceholder={placeholder} />}
        {(checkable || destoryList) && (
          <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}
              </Checkbox>
            )}
            {destoryList && <IconFont type="icon-S_AID_delete" onClick={destoryList} />}
          </div>
        )}

        {!needDnd ? (
          <div className="lm-c-base-list-layout">
            <List className="lm-c-virtual-layout" data={list} rowHeight={30} rowRenderer={this.rowRender} ref={this.listRef} />
          </div>
        ) : (
          <div className="lm-c-base-list-layout" onDragOver={this.dragOver.bind(this)}>
            <ListNonVir className="lm-c-virtual-layout" data={list} rowHeight={30} rowRenderer={this.rowRender} ref={this.listRef} />
          </div>
        )}
      </CBox>
    );
  }
}
