import UpOutlined from '@ant-design/icons/lib/icons/UpOutlined';
import { Tree } from '@easyv/antd';
import classNames from 'classnames';
import { Icon } from 'components/easyDesign';
import EasyvModal, { useConfirmRef } from 'components/EasyvModal';
import message from 'components/message';
import { RootState } from 'models';
import {
  addNavigation,
  deleteNavigationById,
  dispatchUpdateEditPageCurrentTab,
  getPortalDetailById,
  updateCurExpandedNavKeys,
  updateCurSelectedKeys,
  updateNavigationById,
} from 'models/spaceship';
import { NavItemType, SpaceShipState } from 'models/spaceship.types';
import React, { useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
  getCurSelectedKeyById,
  getLevelToChinese,
  jumpByNavConfig,
  pathNameIsSpaceShipEdit,
} from 'utils/spaceship';
import { deepFindOne } from 'utils/utils';
import styles from './treeSelect.less';

interface TreeSelectProps {
  type: 'navDisplay' | 'navSet'; // navSet导航设置 | navDisplay导航展示
}

const { TreeNode } = Tree;

const NavTreeSelect = (props: TreeSelectProps) => {
  const spaceShip = useSelector<RootState>((state) => state.spaceShip) as SpaceShipState;
  const {
    curSelectedKeys,
    curExpandedNavKeys,
    curPortalBaseInfo,
    curPortalNavigation = [],
  } = spaceShip;
  const [dragLevel, setDragLevel] = useState<NavItemType['level']>(1);
  const { type = 'navDisplay' } = props;
  const dispatch = useDispatch();
  const id = Number(window.location.pathname.split('/').pop());
  const modalRef = useConfirmRef();
  const [deletedItem, setDeletedItem] = useState<NavItemType>();
  const [modalContent, setModalContent] = useState('此操作将删除所选菜单，不可恢复，是否继续？');

  const deleteNav = (data: NavItemType) => {
    setDeletedItem(data);
    if (data.children && data.children.length) {
      setModalContent('该菜单包含子菜单，将一并删除，不可恢复，是否继续？');
      modalRef.current?.show();
      return;
    }
    setModalContent('此操作将删除所选菜单，不可恢复，是否继续？');
    modalRef.current?.show();
  };

  const NavActionIcon = useCallback(
    ({ item }) => {
      return (
        <div className={styles.actionIcon} id="actionWrapper">
          {item.level !== 4 && (
            <Icon
              className="whiteHover"
              type="icon_custom1"
              onClick={() => {
                addNavigation({
                  parentId: item.id,
                  name: getLevelToChinese(item.level + 1),
                  portalId: id,
                  quoteType: -1,
                  quotelink: '',
                  screenId: 0,
                  openWay: 1,
                  rank: item.children.length + 1,
                }).then(async (res) => {
                  if (res) {
                    await dispatch(getPortalDetailById(id, res.id));
                    await dispatch(
                      updateCurExpandedNavKeys([
                        ...new Set([
                          ...curExpandedNavKeys.map((item) => String(item)),
                          String(item.id),
                        ]),
                      ]),
                    );
                  }
                });
              }}
              style={{ fontSize: 14 }}
            />
          )}
          <Icon
            className="whiteHover"
            onClick={() => {
              if (item.level === 1 && curPortalNavigation?.length === 1) {
                message.warning('至少保留一个一级菜单');
                return;
              }
              deleteNav(item);
            }}
            type="zd_shanchu"
            style={{ fontSize: 14, marginLeft: 4 }}
          />
        </div>
      );
    },
    [curExpandedNavKeys, curSelectedKeys],
  );

  const renderTree = (data: NavItemType[], type: 'navSet' | 'navDisplay') => {
    return data.map((item) => {
      if (!item.children?.length) {
        return (
          <TreeNode
            title={
              <>
                <span
                  id={`${type}${item.id}`}
                  title={item.name}
                  className={styles.navTitle}
                  style={{ color: type === 'navSet' ? '#fff' : 'inherit' }}>
                  {item.name}
                </span>
                {type === 'navSet' && <NavActionIcon item={item} />}
              </>
            }
            key={item.id}
            {...item}
          />
        );
      } else {
        return (
          <TreeNode
            title={
              <>
                <span
                  id={`${type}${item.id}`}
                  title={item.name}
                  style={{ color: type === 'navSet' ? '#fff' : 'inherit' }}
                  className={styles.navTitle}>
                  {item.name}
                </span>
                {type === 'navSet' && <NavActionIcon item={item} />}
              </>
            }
            key={item.id}
            {...item}>
            {renderTree(item.children || [], type)}
          </TreeNode>
        );
      }
    });
  };
  return (
    <div
      className={classNames(
        type === 'navSet' ? styles.navSet : styles.navDisplay,
        type !== 'navSet' && curPortalBaseInfo?.thumbColor?.name === 'white'
          ? styles.navWhiteTheme
          : styles.navBlackTheme,
      )}>
      <Tree
        selectedKeys={[String(curSelectedKeys)]}
        allowDrop={({ dropNode }: { dropNode: any }) => {
          if (dropNode.level === 4) {
            return false;
          }
          return true;
        }}
        onDrop={(info: any) => {
          // TODO跨级拖拽不允许层级超过4级
          const dropPos = info.node.pos.split('-');
          const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
          // 1.同级拖拽交换位置

          // 2.跨级拖拽{ a.子级往外拖拽 b.外围往里拖拽 }
          if (info.node?.level + dragLevel > 4) {
            message.error('最多可添加4级菜单');
            return;
          }
          if (!info.dropToGap) {
            if (dropPosition === 0) {
              dispatch(
                updateNavigationById({
                  id: info.dragNode.id,
                  portalId: id,
                  rank: 1,
                  parentId: info.node.id,
                }),
              );
            } else {
              dispatch(updateNavigationById({ id: info.dragNode.id, portalId: id, rank: 1 }));
            }
          } else {
            if (dropPosition === -1) {
              dispatch(
                updateNavigationById({ id: info.dragNode.id, portalId: id, rank: 1, parentId: 0 }),
              );
            } else {
              if (dropPosition === 1) {
                if (info.node.level === 1) {
                  dispatch(
                    updateNavigationById({
                      id: info.dragNode.id,
                      portalId: id,
                      rank: info.node.rank + 1,
                      parentId: 0,
                    }),
                  );
                } else {
                  if (info.dragNode.rank < info.node.rank) {
                    dispatch(
                      updateNavigationById({
                        id: info.dragNode.id,
                        portalId: id,
                        rank: info.dropPosition,
                      }),
                    );
                  } else {
                    dispatch(
                      updateNavigationById({
                        id: info.dragNode.id,
                        portalId: id,
                        rank: info.dropPosition + 1,
                      }),
                    );
                  }
                }
              }
            }
          }
        }}
        onDragStart={({ node }: { node: any }) => {
          if (node.children?.length) {
            // 找到当前拖拽菜单最低层的一个子节点
            const res = deepFindOne(
              node.children || [],
              (res) => res?.children?.length === 0 || !res.children,
              'children',
            );
            if (res) {
              const levelNum = res.level - node.level + 1;
              setDragLevel(levelNum as NavItemType['level']);
            }
            return;
          }
          setDragLevel(1);
        }}
        draggable={type === 'navSet'}
        expandedKeys={[...new Set(curExpandedNavKeys.map((item) => String(item)))]}
        blockNode
        showIcon
        onExpand={(expandedKeys: string[]) => {
          dispatch(updateCurExpandedNavKeys(expandedKeys));
        }}
        switcherIcon={
          type == 'navDisplay' ? <UpOutlined style={{ pointerEvents: 'none' }} /> : undefined
        }
        onSelect={(_keys, i: any) => {
          const navData = i.node;
          // 编辑页且为菜单设置则单击行展开收缩
          if (pathNameIsSpaceShipEdit() && type === 'navSet') {
            dispatch(
              updateCurExpandedNavKeys(
                curExpandedNavKeys.includes(navData.key)
                  ? curExpandedNavKeys.filter((item) => item !== navData.key)
                  : [...curExpandedNavKeys, navData.key],
              ),
            );
          }

          if (i.selected) {
            if (navData.key !== curSelectedKeys) {
              dispatch(dispatchUpdateEditPageCurrentTab('1'));
            }
            // 如果是编辑页则任何引用类型的菜单都可以被选中
            if (pathNameIsSpaceShipEdit()) {
              document
                .getElementById(
                  type === 'navSet' ? `navDisplay${navData.key}` : `navSet${navData.key}`,
                )
                ?.scrollIntoView(true);
              dispatch(updateCurSelectedKeys(Number(navData.key)));
              return;
            }

            // 非编辑页，且当前选中为空节点，则查找当前空节点子节点存在引用类型为外链或者应用的
            if (navData.quoteType === 0) {
              const curSelectedChildrenData = getCurSelectedKeyById(navData.children || []);
              if (Object.keys(curSelectedChildrenData).length) {
                document
                  .getElementById(
                    type === 'navSet'
                      ? `navDisplay${curSelectedChildrenData.id}`
                      : `navSet${curSelectedChildrenData.id}`,
                  )
                  ?.scrollIntoView(true);
                dispatch(updateCurSelectedKeys(Number(curSelectedChildrenData.id)));
              }
              return;
            }

            //  非编辑页，且当新建页面打开
            if (navData.openWay === 2) {
              jumpByNavConfig(navData);
              return;
            }
            // 非编辑页，且当前选中菜单引用类型不为空节点
            document
              .getElementById(
                type === 'navSet' ? `navDisplay${navData.key}` : `navSet${navData.key}`,
              )
              ?.scrollIntoView(true);
            dispatch(updateCurSelectedKeys(Number(navData.key)));
            return;
          }
        }}>
        {renderTree(curPortalNavigation || [], type)}
      </Tree>
      <EasyvModal.Confirm
        onOk={() => dispatch(deleteNavigationById(deletedItem?.id, id))}
        iconType="warning"
        content={modalContent}
        ref={modalRef}
        title="删除菜单"
      />
    </div>
  );
};
export default NavTreeSelect;
