import {useContextSection} from '@hooks';
import {context} from './context';
import {FormEvent, useEffect} from 'react';
import {useMutation, useQueryClient} from '@tanstack/react-query';
import {editRoleMenu, getRoleList, getTreeMenu} from '@apis';
import {message} from 'antd';
import {RoleListData, TreeMenuListData} from '@models';
import {pageContext} from '@pages/role/context';

function useEditMenu(onClose: () => void, onFetch: () => void) {
  const {isLoading, mutate} = useMutation(editRoleMenu, {
    onSuccess({msg}) {
      if (msg === '200') {
        message.success('设置成功');
        onClose();
        onFetch();
      }
    },
  });

  return [isLoading, mutate] as const;
}

function useTreeMap() {
  const client = useQueryClient();

  function parseParentIdMap() {
    const map = new Map<string, string>();

    const treeData = client.getQueryData<TreeMenuListData[]>([
      getTreeMenu.name,
    ]);
    if (!treeData || treeData.length === 0) return map;

    function deepTree(tree: TreeMenuListData[]) {
      tree.forEach(function ({pId, key, children}) {
        // 一级菜单不参与寻找父级id
        pId !== '0' && map.set(key, pId);

        children.length && deepTree(children);
      });
    }

    deepTree(treeData);

    return map;
  }

  return parseParentIdMap;
}

export function useSubmit({
  id,
  onClose,
  onFetch,
}: {
  id: string;
  onClose: () => void;
  onFetch: () => void;
}) {
  const list = useContextSection(context, ([list]) => list);
  const [isLoading, mutate] = useEditMenu(onClose, onFetch);
  const parseTreeMap = useTreeMap();

  function parseMenuTreeList(list: string) {
    const trees = list.split(',');
    const menuSet = new Set(),
      antdSet = new Set();
    const treeMap = parseTreeMap();

    trees.forEach(function (val) {
      // 传给后台的要子菜单和父菜单的id
      menuSet.add(val);

      const pId = treeMap.get(val);

      // 如果有pId说明是二级菜单 antd中需要添加
      // 同时需要向menuSet中添加 确保所有的二级菜单的父级都包含

      if (pId) {
        menuSet.add(pId);
        antdSet.add(val);
      }
    });

    const menu = [...menuSet].join(','),
      antd = [...antdSet].join(',');

    return {
      menu: `${menu}${menu ? ',' : ''}`,
      antd,
    };
  }

  function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();

    const listStr = list.join(',');
    const {antd, menu} = parseMenuTreeList(listStr);

    mutate({
      id,
      menu,
      menuBefore: antd,
    });
  }

  return [isLoading, onSubmit] as const;
}

export function useWatchId(id: string, visible: boolean) {
  const client = useQueryClient();
  const dispatch = useContextSection(context, ([, dispatch]) => dispatch);
  const {page, pageSize} = useContextSection(pageContext, state => state[0]);

  useEffect(
    function () {
      if (!visible) return;

      const data = client.getQueryData<RoleListData[]>(
        [getRoleList.name, page, pageSize],
        {
          exact: false,
        },
      );

      const res = data?.find(val => String(val.id) === id);

      if (res) {
        const menuList = res?.menuBefore ? res.menuBefore.split(',') : [];

        dispatch(menuList);
      }
    },
    [id, client, dispatch, visible, page, pageSize],
  );
}
