import React, { useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { Button, Input, Radio, Modal, Checkbox, Row, Col, Tree, ConfigProvider } from 'antd';
import Empty from '@wisdom-components/empty';
import { ExclamationCircleFilled, SearchOutlined, CloseOutlined } from '@ant-design/icons';
import './index.less';

const { TreeNode } = Tree;

const QuotaSelect = ({
  buttonProps,
  width,
  title,
  cancelText,
  okText,
  onModalOk,
  onModalCancel,
  onModalClose,
  searchPrefix,
  placeholder,
  maximum,
  dataSource,
  selectData,
  onCheckboxChange,
  onCancelSelect,
  treeProps,
  onTreeDrop,
}) => {
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('quota-select');

  const [visible, setVisible] = useState(false);
  const [targetValue, setTargetValue] = useState('emphasis');
  const [allQuotaList, setAllQuotaList] = useState([]);
  const [quotaList, setQuotaList] = useState([]);

  useEffect(() => {
    if (dataSource.length > 0) {
      let data = dataSource.map((item) => ({
        ...item,
        checked: false,
        title: item.name,
        key: item.name,
      }));
      setAllQuotaList(data);
    }
  }, [dataSource]);

  useEffect(() => {
    if (targetValue === 'emphasis') {
      filterEmphasisQuota();
    }
  }, [allQuotaList]);

  useEffect(() => {
    let data = [...allQuotaList];
    data.forEach((item) => {
      item.checked = false;
      if (selectData.length > 0) {
        selectData.forEach((child) => {
          if (child.key === item.key) {
            item.checked = true;
          }
        });
      }
    });
    setAllQuotaList(data);
  }, [selectData]);

  // 过滤重点指标
  const filterEmphasisQuota = () => {
    let newQuotaList = [...allQuotaList];
    newQuotaList = newQuotaList.filter((item) => item.isShow === '1');
    setQuotaList(newQuotaList);
  };

  // 展示模态框
  const showModal = () => {
    setVisible(true);
  };

  // 关闭模态框
  const handleCancel = (e) => {
    if (e.target.innerHTML === cancelText) {
      onModalCancel && onModalCancel();
    } else {
      onModalClose && onModalClose();
      setVisible(false);
    }
  };

  const onOk = () => {
    onModalOk && onModalOk();
    setVisible(false);
  };

  // 切换重点与全部
  const onRadioChange = (e) => {
    if (e.target.value === 'all') {
      setQuotaList(allQuotaList);
    } else {
      filterEmphasisQuota();
    }
    setTargetValue(e.target.value);
  };

  // 搜索指标
  const onSearch = (e) => {
    if (e.type === 'keydown' || e.target.value === '') {
      if (e.target.value !== '') {
        let newQuotaList = [];
        quotaList.forEach((item) => {
          if (item.name.indexOf(e.target.value) > -1) newQuotaList.push(item);
        });
        setQuotaList(newQuotaList);
      } else {
        if (targetValue === 'all') {
          setQuotaList(allQuotaList);
        } else {
          filterEmphasisQuota();
        }
      }
    }
  };

  // 处理复选框点击事件
  const handleCheckboxChange = (e) => {
    let newQuotaList = [...allQuotaList];
    let curSelectKey = [];
    let curSelectList = [...selectData];
    let data = curSelectList.filter((item) => item.title === e.target.value);
    if (data.length) {
      curSelectList = curSelectList.filter((item) => item.title !== e.target.value);
    } else {
      curSelectList.push({ key: e.target.value, title: e.target.value });
    }
    newQuotaList.forEach((item) => {
      if (item.title === e.target.value) {
        item.checked = !item.checked;
      }
    });
    curSelectKey = curSelectList.map((item) => item.key);
    onCheckboxChange({
      selectKey: curSelectKey,
      selectList: curSelectList,
    });
    setAllQuotaList(newQuotaList);
  };

  // 处理取消选择按钮点击事件
  const handleCancelSelect = ({ title }) => {
    let data = [...selectData];
    data = data.filter((item) => item.title !== title);
    onCancelSelect({
      selectKey: data.map((item) => item.key),
      selectList: data,
    });
  };

  // 拖动选中树节点
  const handleDrop = (info) => {
    const dropKey = info.node.key;
    const dragKey = info.dragNode.key;
    const dropPos = info.node.pos.split('-');
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

    const loop = (data, key, callback) => {
      for (let i = 0; i < data.length; i++) {
        if (data[i].key === key) {
          return callback(data[i], i, data);
        }
        if (data[i].children) {
          loop(data[i].children, key, callback);
        }
      }
    };

    const data = [...selectData];

    let dragObj;
    loop(data, dragKey, (item, index, arr) => {
      arr.splice(index, 1);
      dragObj = item;
    });

    if (!info.dropToGap) {
      loop(data, dropKey, (item) => {
        item.children = item.children || [];
        item.children.unshift(dragObj);
      });
    } else if (
      (info.node.props.children || []).length > 0 && // Has children
      info.node.props.expanded && // Is expanded
      dropPosition === 1 // On the bottom gap
    ) {
      loop(data, dropKey, (item) => {
        item.children = item.children || [];
        item.children.unshift(dragObj);
      });
    } else {
      let ar;
      let i;
      loop(data, dropKey, (item, index, arr) => {
        ar = arr;
        i = index;
      });
      if (dropPosition === -1) {
        ar.splice(i, 0, dragObj);
      } else {
        ar.splice(i + 1, 0, dragObj);
      }
    }

    onTreeDrop({
      selectKey: data.map((item) => item.key),
      selectList: data,
    });
  };

  return (
    <div className={classNames(prefixCls)}>
      <Button {...buttonProps} onClick={showModal} />
      {visible && (
        <Modal
          centered
          width={width}
          title={title}
          cancelText={cancelText}
          okText={okText}
          visible={true}
          onCancel={handleCancel}
          onOk={onOk}
          className={classNames(`${prefixCls}-modal`)}
        >
          <div className={classNames(`${prefixCls}-modal-wrap`)}>
            <div className={classNames(`${prefixCls}-modal-left`)}>
              <div className={classNames(`${prefixCls}-modal-select-wrap`)}>
                <Input
                  className={classNames(`${prefixCls}-modal-search`)}
                  placeholder={placeholder}
                  bordered={false}
                  prefix={searchPrefix}
                  onChange={onSearch}
                  onPressEnter={onSearch}
                />
                <div className={classNames(`${prefixCls}-modal-target`)}>
                  <div>指标：</div>
                  <Radio.Group onChange={onRadioChange} defaultValue={targetValue}>
                    <Radio.Button value="emphasis">重点指标</Radio.Button>
                    <Radio.Button value="all">全部</Radio.Button>
                  </Radio.Group>
                </div>
                <div
                  className={classNames(`${prefixCls}-modal-select`, {
                    warning: !(selectData.length < maximum),
                  })}
                >
                  {selectData.length < maximum ? (
                    <>
                      <ExclamationCircleFilled />
                      <div>已选择 {selectData.length} 个指标</div>
                    </>
                  ) : (
                    <>
                      <ExclamationCircleFilled />
                      <div>已达上限，最多选择 {maximum} 个指标</div>
                    </>
                  )}
                </div>
              </div>
              <div className={classNames(`${prefixCls}-modal-option-wrap`)}>
                {!quotaList.length && <Empty />}
                <Row gutter={[0, 6]}>
                  {!!quotaList.length &&
                    quotaList.map((item) => (
                      <Col span={8} key={item.key}>
                        <Checkbox
                          value={item.title}
                          checked={item.checked}
                          disabled={
                            (selectData.length > maximum || selectData.length === maximum) &&
                            !item.checked
                          }
                          onChange={handleCheckboxChange}
                        >
                          {item.title}
                        </Checkbox>
                      </Col>
                    ))}
                </Row>
              </div>
            </div>
            <div className={classNames(`${prefixCls}-modal-right`)}>
              <div className={classNames(`${prefixCls}-modal-number`)}>
                已选：{selectData.length}/{maximum}
              </div>
              <div className={classNames(`${prefixCls}-modal-tree`)}>
                <Tree draggable={true} onDrop={handleDrop} {...treeProps}>
                  {selectData.map((item) => (
                    <TreeNode
                      key={item.key}
                      title={
                        <div className={classNames(`${prefixCls}-modal-tree-title`)}>
                          <div>{item.title}</div>
                          <CloseOutlined onClick={() => handleCancelSelect(item)} />
                        </div>
                      }
                    />
                  ))}
                </Tree>
              </div>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
};

QuotaSelect.defaultProps = {
  buttonProps: {},
  width: 900,
  title: '选择显示字段',
  cancelText: '取消选择',
  okText: '确定',
  placeholder: '搜索关键词',
  searchPrefix: <SearchOutlined />,
  maximum: 0,
  dataSource: [],
  selectData: [],
  treeProps: {},
  onModalCancel: () => {},
  onModalOk: () => {},
  onModalClose: () => {},
  onCancelSelect: () => {},
  onTreeDrop: () => {},
};

QuotaSelect.propTypes = {
  buttonProps: PropTypes.object,
  width: PropTypes.number,
  title: PropTypes.string,
  cancelText: PropTypes.string,
  okText: PropTypes.string,
  placeholder: PropTypes.string,
  searchPrefix: PropTypes.node,
  maximum: PropTypes.number,
  dataSource: PropTypes.array,
  selectData: PropTypes.array,
  treeProps: PropTypes.object,
  onModalCancel: PropTypes.func,
  onModalOk: PropTypes.func,
  onModalClose: PropTypes.func,
  onCancelSelect: PropTypes.func,
  onTreeDrop: PropTypes.func,
};

export default QuotaSelect;
