import React, { useState, useEffect, useCallback, useRef } from 'react';
import { connect } from 'react-redux';
import { Drawer, Checkbox } from '@easyv/react-gui';
import { Row, Col, Space, Spin, Tree, Tooltip } from '@easyv/antd';
import { LoadingOutlined, InfoCircleOutlined } from '@ant-design/icons';
import { getRecycleBin, delRecycleBin, resetRecycleBin } from 'models/commentDelted';
import { getPanelInfoForScreenEdit } from 'models/panel';
import { resetComponent } from 'models/component';
import styles from './CommentDeleted.less';
import classnames from 'classnames';
const { DirectoryTree } = Tree;
import iconTypes from './icon.type.json';
import { format } from 'utils/utils';
import message from 'components/message';
import EasyvButton from 'components/EasyvButton';
import EasyvModal, { useConfirmRef } from 'components/EasyvModal';
import once from 'lodash/once';
import { CloseOutlined } from '@easyv/react-icons';

interface listType {
  id: number;
  name: string;
  componentId: string | number;
}

function CommentDelted({
  children,
  screensById,
  createApp,
  recycleBinData,
  resetComponent,
  getRecycleBin,
  delRecycleBin,
  resetRecycleBin,
  getPanel,
  setActive,
}) {
  const [visible, setVisible] = useState(false);
  const [indeterminate, setIndeterminate] = useState(false); // true 半选中，false 未选中
  const [checkAll, setCheckAll] = useState(false);
  const [loading, setLoading] = useState(false);
  const [checkArr, setCheckArr] = useState<number[]>([]);
  const containerRef = useRef<HTMLDivElement>(null);
  const [list, setList] = useState<listType[]>([]);
  const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
  const intervalDate = 24 * 60 * 60 * 1000; //24小时
  const deleteRef = useConfirmRef();

  useEffect(() => {
    const handleClick = (e) => {
      if (!containerRef.current?.contains(e.target)) {
        const appDOM = document.getElementById('easyv-app');
        if (appDOM && appDOM.contains(e.target)) {
          setVisible(false);
        }
      }
    };

    document.addEventListener('click', handleClick, false);

    return () => {
      document.removeEventListener('click', handleClick, false);
    };
  }, []);

  useEffect(() => {
    const defaultIcon = 'icon-btn_regular';
    if (visible) {
      const nowDate = Date.now();
      const { id: screenId } = createApp;
      const layers = screensById[screenId].layers;
      const newRecycleBinData = recycleBinData.map((e) => {
        const endeTime = e.recycledAt + intervalDate;
        let parent: any = null;
        if (e.detail.parent) {
          // 有父组件
          parent = layers.filter((item) => {
            return item.id === e.detail.parent;
          });
          parent = parent && typeof parent === 'object' && parent.length ? parent[0] : false;
        }
        let iconName = (e.detail.module && iconTypes[e.detail.module.category]) || defaultIcon;
        if (e.componentId.indexOf('panel_') > -1) {
          // 动态面板
          iconName = 'icon-btn_panel';
        } else if (e.componentId.indexOf('ref_') > -1) {
          // 引用面板
          iconName = 'icon-icon_link';
        }
        if (e.detail.childComponents && e.detail.childComponents.length) {
          e.detail.componentList = getTreeData(e.detail);
        } else if (e.detail.components && e.detail.components.length) {
          e.detail.componentList = getTreeData(e.detail);
        }
        return {
          ...e,
          parentData: parent,
          iconName: iconName, // iconTypes
          recycledAStr: e.recycledAt ? format(new Date(e.recycledAt), '/') : '/',
          timeRemaining:
            endeTime - nowDate > 0 ? Math.ceil((endeTime - nowDate) / (1 * 60 * 60 * 1000)) : 0,
        };
      });
      setList(newRecycleBinData);
    }
  }, [recycleBinData]);

  useEffect(() => {
    setActive && setActive(visible);
  }, [visible]);

  const commentDelted = async () => {
    // 组件回收站
    if (visible) {
      setVisible(false);
      return false;
    }
    setList([]);
    setVisible(true);
    setLoading(true);
    const res = await getRecycleBin();
    if (!res) {
      setList([]);
    }
    setLoading(false);
  };
  const onClose = useCallback(() => {
    setVisible(false);
  }, []);

  const onCheckAllChange = (e) => {
    // 全选
    setIndeterminate(false);
    if (e.target && e.target.checked) {
      setCheckAll(true);
      const allIds = list.map((e: listType) => {
        return e.id;
      });
      setCheckArr(allIds);
    } else {
      setCheckAll(false);
      setCheckArr([]);
    }
  };

  useEffect(() => {
    const allIds = list.map((e) => {
      return e.id;
    });
    if (!allIds.length || !checkArr.length) {
      setIndeterminate(false);
      setCheckAll(false);
    } else if (allIds.length != checkArr.length) {
      setIndeterminate(true);
    } else {
      setIndeterminate(false);
      setCheckAll(true);
    }
  }, [checkArr, list]);

  const onRecovery = async () => {
    const hide = message.loading('处理中...', 0);
    const res = await resetRecycleBin(checkArr);
    if (res) {
      for (let i = 0; i < list.length; i++) {
        // 属于被删除的项，且输入动态面板
        const card = list[i].componentId;
        if (checkArr.includes(list[i].id) && typeof card === 'string') {
          // 如果属于动态面板，就拉取动态面板数据
          card.indexOf('panel_') > -1 && getPanel(card.split('panel_')[1]);
          card.indexOf('ref_') > -1 && getPanel(card.split('ref_')[1]);
        }
      }
      // 重新拉取组件数据
      resetComponent(res.components);
      setCheckArr([]);
      await hide();
    }
  };

  const treeForeach = (tree, list) => {
    tree &&
      tree.length &&
      tree.forEach((data, index) => {
        let icon = data.module && iconTypes[data.module.category];
        if (!icon) {
          icon = iconTypes[data.name];
        }
        const components = data.components || data.childComponents;
        list.push({
          title: data.name,
          key: data.id + '-' + index,
          icon: <i className={`icon iconfont ${icon || 'icon-zu'}`} />,
          children: components ? treeForeach(components, []) : [],
        });
      });
    return list;
  };
  const getTreeData = (detail: {
    components: [];
    childComponents: [];
    module: { category: string };
    id: number;
    uniqueTag: string;
    name: string;
  }) => {
    const tree = treeForeach(detail.components || detail.childComponents, []);
    let icon = 'icon-zu';
    const _idStr: boolean = typeof detail.id === 'number';
    if (_idStr) {
      icon = detail.module && iconTypes[detail.module.category];
    }
    return [
      {
        title: detail.name,
        key: detail.id,
        icon: <i className={`icon iconfont ${icon}`} />,
        children: tree,
      },
    ];
  };

  const DrawerTitle = (
    <div className={styles.drawerTitle}>
      <div className={styles.title}>
        <span className={styles.drawerTn}>组件回收站</span>
        <em className={styles.drawerTip}>删除的组件会在组件回收站保存24小时，之后将彻底删除</em>
      </div>
      <CloseOutlined
        onClick={() => {
          onClose?.();
        }}
        className={styles.close}
      />
    </div>
  );

  return (
    <div className={styles.delted} ref={containerRef}>
      <div className={styles.commentDelted} onClick={commentDelted}>
        {children}
      </div>
      <Drawer
        className={`${styles.drawer} ${styles.painter}`}
        destroyOnClose={true} //实时销毁子元素
        title={DrawerTitle}
        placement={'right'}
        width={520}
        mask={false}
        closable={false}
        onClose={onClose}
        visible={visible}
        key={'right'}
      >
        <div className={styles.tableBox}>
          <div className={styles.header}>
            <Row>
              <Col span={8}>
                <Checkbox
                  style={{ color: '#FAFAFA', fontSize: '14px' }}
                  indeterminate={indeterminate}
                  onChange={onCheckAllChange}
                  checked={checkAll}
                >
                  全选
                </Checkbox>
                <span
                  style={{
                    color: `rgba(255, 255, 255, 0.5)`,
                    fontSize: 14,
                  }}
                >
                  （<span className={styles.countName}>{checkArr.length}</span>/{list.length}）
                </span>
              </Col>
              <Col span={8} offset={8} style={{ textAlign: 'right' }}>
                <Space>
                  <EasyvButton
                    theme="ghost"
                    size="small"
                    onClick={once(() => {
                      deleteRef.current?.show();
                    })}
                    disabled={!checkArr.length}
                  >
                    删除
                  </EasyvButton>
                  <EasyvButton
                    theme="primary"
                    onClick={onRecovery}
                    size="small"
                    disabled={!checkArr.length}
                  >
                    恢复
                  </EasyvButton>
                </Space>
              </Col>
            </Row>
          </div>
          <div className={styles.cols}>
            {loading ? (
              <div style={{ textAlign: 'center', margin: '20px 0' }}>
                <Spin indicator={antIcon} />
              </div>
            ) : (
              <ul>
                <Checkbox.Group
                  style={{ width: '100%' }}
                  value={checkArr}
                  onChange={(lis) => {
                    setCheckArr(lis);
                  }}
                >
                  {list && list.length ? (
                    list.map((e: any) => {
                      return (
                        <li key={e.id} className={styles.li}>
                          {e.parentData ? (
                            <div className={styles.parentRow}>
                              <div className={styles.parentName}>
                                <span>{e.parentData.name}</span>
                              </div>
                            </div>
                          ) : null}
                          <div className={styles.item}>
                            <div className={styles.checkboxItem}>
                              <Checkbox disabled={e.parentData === false} value={e.id}></Checkbox>
                            </div>
                            {e.detail && e.detail.componentList ? (
                              <div className={styles.treBox}>
                                <DirectoryTree
                                  multiple
                                  blockNode
                                  treeData={e.detail.componentList}
                                />
                                <Row
                                  className={classnames([styles.itemRow, styles.itemTree])}
                                  align="top"
                                  justify="center"
                                >
                                  <Col span={8} offset={10}>
                                    <span className={styles.itemTime}>{e.recycledAStr}</span>
                                  </Col>
                                  <Col span={6} style={{ textAlign: 'right' }}>
                                    <span className={styles.itemEndTime}>
                                      剩余{e.timeRemaining}小时
                                    </span>
                                  </Col>
                                </Row>
                              </div>
                            ) : (
                              <Row className={styles.itemRow} align="middle" justify="center">
                                <Col span={10}>
                                  <div className={classnames([styles.col])}>
                                    <div
                                      style={{
                                        display: 'flex',
                                        alignItems: 'center',
                                      }}
                                    >
                                      <div
                                        className={classnames([
                                          styles.itemCover,
                                          styles.marginLeft,
                                        ])}
                                      >
                                        <i className={`icon iconfont ${e.iconName}`} />
                                      </div>
                                      <span className={styles.itemTitle}>
                                        {e.detail.name || e.detail.componentName}
                                      </span>
                                      {e.parentData === false ? (
                                        <Tooltip
                                          color="#F77A21"
                                          placement="top"
                                          title={`父组件被删除无法恢复`}
                                        >
                                          <InfoCircleOutlined
                                            style={{ color: '#F77A21', marginLeft: '5px' }}
                                          />
                                        </Tooltip>
                                      ) : null}
                                    </div>
                                  </div>
                                </Col>
                                <Col span={8}>
                                  <span className={styles.itemTime}>{e.recycledAStr}</span>
                                </Col>
                                <Col span={6} style={{ textAlign: 'right' }}>
                                  <span className={styles.itemEndTime}>
                                    剩余{e.timeRemaining}小时
                                  </span>
                                </Col>
                              </Row>
                            )}
                          </div>
                        </li>
                      );
                    })
                  ) : (
                    <span className={styles.noData}>暂无数据</span>
                  )}
                </Checkbox.Group>
              </ul>
            )}
          </div>
        </div>
      </Drawer>
      <EasyvModal.Confirm
        onOk={async () => {
          deleteRef.current?.close();
          const res = await delRecycleBin(checkArr);
          if (res) {
            setCheckArr([]);
          }
        }}
        title="删除组件"
        content="此操作将删除所选组件，不可恢复，是否继续？"
        ref={deleteRef}
      />
    </div>
  );
}

const mapStateToProps = ({ createApp, screensById, recycleBinData }) => {
  return { recycleBinData, createApp, screensById };
};
const mapDispatchToProps = {
  getRecycleBin,
  delRecycleBin,
  resetRecycleBin,
  resetComponent,
  getPanel: getPanelInfoForScreenEdit,
};
export default connect(mapStateToProps, mapDispatchToProps)(CommentDelted);
