import classNames from 'classnames';
import EasyvEmpty from 'components/EasyvEmpty';
import EasyvScrollContainer from 'components/EasyvScrollContainer';
import EasyvTree from 'components/EasyvTree';
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
import { PasteMultipleComponentRef, PasteMultipleComponentType, SelectedKeysType } from './type';
import { getChangedConfigByCheckedKeys, getMultipleSelectedKeys } from './util';
import { RightOutlined } from '@easyv/react-icons';
import styles from './style.less';
import { Utils } from '@easyv/react-gui';
const { mergeStyleConfig } = Utils;

const RenderComConfigTree = ({ comConfigList, curComponentId, checkedKeys, treeData, onCheck }) => {
  return comConfigList.find((item) => item.componentId === curComponentId)?.comConfigTreeData
    .length ? (
    <EasyvScrollContainer className={styles.rightContainer}>
      <div style={{ height: 600 }}>
        <EasyvTree
          checkedKeys={checkedKeys}
          onCheck={(checkedKeys, info) => onCheck(checkedKeys, info, curComponentId)}
          treeData={treeData}
          selectable={false}
          defaultExpandAll={false}
        />
      </div>
    </EasyvScrollContainer>
  ) : (
    <EasyvEmpty className={styles.noDataContainer} description="无可粘贴的组件样式" />
  );
};

const PasteMultipleComponent = forwardRef<PasteMultipleComponentRef, PasteMultipleComponentType>(
  (props, ref) => {
    const { comConfigList = [], onChangeCheckedAllStatus } = props;
    const [curComponentId, setCurComponentId] = useState(comConfigList?.[0]?.componentId);

    const [selectedKeys, setSelectedKeys] = useState<SelectedKeysType[]>(
      getMultipleSelectedKeys(comConfigList) || [],
    );

    const treeData = useMemo(
      () => comConfigList.find((i) => i.componentId === curComponentId)?.comConfigTreeData || [],
      [comConfigList, curComponentId],
    );

    const checkedKeys = useMemo(
      () => selectedKeys.find((i) => i.componentId === curComponentId)?.checkedKeys || [],
      [selectedKeys, curComponentId],
    );

    useEffect(() => {
      const curSelectedConfig = selectedKeys.find((i) => i.componentId === curComponentId);
      onChangeCheckedAllStatus(
        curSelectedConfig?.defaultAllKeys?.length === curSelectedConfig?.checkedKeys.length
          ? '取消全选'
          : '全选',
      );
    }, [curComponentId, selectedKeys]);

    const updateSelectedKeysBySelectedType = (data, id, curSelectedConfig, type) => {
      const newData = data.map((cur) => {
        if (cur.componentId === id) {
          return {
            componentId: id,
            checkedKeys: type ? curSelectedConfig?.defaultAllKeys || [] : [],
            defaultAllKeys: curSelectedConfig?.defaultAllKeys,
            halfCheckedKeys: [],
          };
        } else {
          return cur;
        }
      });
      setSelectedKeys(newData);
      onChangeCheckedAllStatus(type ? '取消全选' : '全选');
    };

    useImperativeHandle(
      ref,
      () => ({
        getUpdateConfig: () => {
          const data = selectedKeys.reduce((pre, item) => {
            const { checkedKeys, componentId } = item;
            const curFindOne = comConfigList.find((o) => o.componentId === componentId);
            const { sourceConfig = [], copyedConfig = [] } = curFindOne || {};
            if (checkedKeys.length) {
              return [
                ...pre,
                {
                  componentId,
                  updateData: {
                    config: mergeStyleConfig(
                      sourceConfig,
                      getChangedConfigByCheckedKeys(
                        copyedConfig,
                        checkedKeys.concat(item.halfCheckedKeys),
                      ),
                    ),
                  },
                },
              ];
            } else {
              return pre;
            }
          }, []);
          return data;
        },
        onCheckedAll: () => {
          const curSelectedConfig = selectedKeys.find((i) => i.componentId === curComponentId);
          updateSelectedKeysBySelectedType(
            selectedKeys,
            curComponentId,
            curSelectedConfig,
            !(curSelectedConfig?.checkedKeys.length === curSelectedConfig?.defaultAllKeys?.length),
          );
        },
      }),
      [selectedKeys, curComponentId, comConfigList],
    );

    const onCheck = (checkedKeys, info, componentId) => {
      const newData = selectedKeys.map((item) => {
        if (item.componentId === componentId) {
          return { ...item, checkedKeys, halfCheckedKeys: info.halfCheckedKeys };
        } else {
          return item;
        }
      });
      setSelectedKeys(newData);
    };

    return (
      <div className={styles.multipleComponentContainer}>
        <EasyvScrollContainer className={styles.leftContainer}>
          {comConfigList.map((item) => (
            <div
              key={item.componentId}
              onClick={() => setCurComponentId(item.componentId)}
              className={classNames(
                styles.componentTitle,
                curComponentId === item.componentId ? styles.selected : null,
              )}>
              <span className={styles.text}>{item.componentName}</span>
              <RightOutlined className={styles.iconRight} />
            </div>
          ))}
        </EasyvScrollContainer>
        <RenderComConfigTree
          comConfigList={comConfigList}
          curComponentId={curComponentId}
          checkedKeys={checkedKeys}
          treeData={treeData}
          onCheck={onCheck}
        />
      </div>
    );
  },
);

export default PasteMultipleComponent;
