import { ref } from "vue";
import { concat, findIndex } from "lodash-es";
import {
  TRenderType,
  ERenderType,
  TEmployeeData,
  TEmployeeDeptData,
  TLetterData,
  TRenderData,
  TOriginData,
  TDepartmentData,
} from "../../type";
import { getUniqueKey } from "../utils/utils";
import { getTopFiveEmployeeData } from "../api/index";
const useEmployeeData = () => {
  const letterData = ref<string[]>([]);
  const employeeData = ref<TEmployeeData[]>([]);
  const deptData = ref<TEmployeeDeptData[]>([]);
  const homeStaffData = ref<TRenderData[]>([]);
  let topFiveEmployeeData: TEmployeeData[] = [];
  //用于处理一个员工存在于多个部门的场景，后端只返回上级部门id，只有首页数据有
  const mapEmployeeData: Record<string, TEmployeeData> = {};
  //用作用户id和部门id的映射关系，因为top5接口没办法返回部门id
  const mapDepartmentId: Record<string, string[]> = {};
  const treeData = ref();

  /**
   * 将单词栏目单独提取一列用于虚拟滚动渲染
   * [{"id":"1","name":"don","initial":"B"}]
   * 变成
   * [
   *  {"id":"1","initial":"B"}
   *  {"id":"1","name":"don","initial":"B"}
   * ]
   */
  const onExtractLetter = (list: TEmployeeData[]): TRenderData[] => {
    let letter = "";
    let arr: TRenderData[] = [];
    list.forEach((item) => {
      if (item.initial !== letter) {
        letter = item.initial;
        arr = [...arr, createLetterData(item.initial), item];
      } else {
        arr = [...arr, item];
      }
    }, []);
    return arr;
  };

  //生成字母标题的数据
  const createLetterData = (letter: string): TLetterData => {
    return {
      id: letter,
      key: letter,
      initial: letter,
      renderType: "initial",
    };
  };

  const onGetTopFiveEmployeeData = async () => {
    const result = await getTopFiveEmployeeData({ scene: 1 });
    const list = result?.data?.data_list ?? [];
    topFiveEmployeeData = list.slice(0, 5).map((res) => {
      return {
        ...res,
        key: `zjcx-${res.id}`,
        initial: "最近常选",
        renderType: "employee",
        parentIds: mapDepartmentId[res.id],
      };
    });
  };

  /**
   * 获取对应部门下的员工信息
   * @param departmentId 部门id
   * @param isOnlySub 是否只获取下一级员工还是当前部门下所有员工
   * @returns
   */
  const onGetSubEmployeeData = (parentId: string): TEmployeeData[] => {
    if (!parentId) {
      return employeeData.value;
    } else {
      return employeeData.value.filter((res) =>
        res.parentIds.includes(parentId),
      );
    }
  };

  const onGetRenderData = async (showRecentChoose: boolean) => {
    letterData.value = employeeData.value.reduce((acc, item) => {
      if (item.initial && !acc.includes(item.initial)) acc.push(item.initial);
      return acc;
    }, []);
    await onGetTopFiveEmployeeData();
    const topFiveList =
      topFiveEmployeeData.length > 0 && showRecentChoose
        ? [createLetterData("最近常选"), ...topFiveEmployeeData]
        : [];
    homeStaffData.value = concat(
      topFiveList,
      onExtractLetter(employeeData.value),
    );
  };

  //默认员工数据只包含上级部门id，但是判断部门选中状态需要员工数据中包含的所有部门id，所以做转换
  const onEmployeeDataAddAllDept = (data: TEmployeeData): TEmployeeData => {
    return mapEmployeeData[getUniqueKey(data.id, data.parentId)];
  };

  //选择最近常选的员工，因为接口没有parentId，所以需要通过id查询employeeData
  const onEmployeeDataAddTopFive = (data: TEmployeeData): TEmployeeData => {
    return employeeData.value.find((res) => res.id === data.id);
  };

  const onGetDepartmentData = (data: TOriginData[]) => {
    const employeeList: TEmployeeData[] = [];
    const employeeSortIdList: Record<string, number> = {};
    //将数组转成树
    const useArrToTree = (arr: TOriginData[]): TDepartmentData[] => {
      const returnArr = [];
      const map = arr.reduce((acc, item, index) => {
        if (item.type === 2)
          employeeSortIdList[getUniqueKey(item.id, item.pid)] = index;
        acc[item.id] = item;
        return acc;
      }, {});
      const len = arr.length;
      for (let i = 0; i < len; i++) {
        if (!arr[i].pid || arr[i].pid === "0") returnArr.push(arr[i]);
        const item = map[arr[i].pid];
        if (item) item.children = [...(item.children ?? []), arr[i]];
      }
      return returnArr;
    };

    /***
     * @description: 处理数据
     * @param {*} init_data 初始数据
     * @param {*} pids 调用时不用传，表示当前节点的上级id
     * @return {*} 返回带上parent和children的id数据
     */
    const treeFilter = (data: TOriginData[] = [], pids = []) => {
      const res = data.map((ele: TOriginData) => {
        const {
          children = [],
          id,
          type,
          pid,
          name = "",
          alias,
          count,
          avatar,
          saas_status,
          status,
          initial,
          userid_third,
        } = ele ?? {};
        const childrenList = treeFilter(children, [id, ...pids]);
        const childrenIds = childrenList.reduce((pre, cur) => {
          const { id = "", childrenIds = [] } = cur;
          return [...pre, id, ...childrenIds];
        }, []);
        const common = {
          id,
          key: id,
          name,
          parentId: pid,
          parentIds: pids,
          renderType: ERenderType[type] as TRenderType,
        };
        //1的话是部门
        if (type === 1) {
          const departmentInfo = {
            ...common,
            count,
            children: childrenList,
            childrenIds,
          };
          return departmentInfo;
          //2的话是员工
        } else if (type === 2) {
          const employeeInfo = {
            ...common,
            alias,
            avatar,
            initial,
            isQuit: status === 5,
            isForbidden: saas_status === 0,
            userid_third: userid_third,
          };
          employeeList[employeeSortIdList[getUniqueKey(id, pid)]] =
            employeeInfo;
          mapEmployeeData[`${id}-${pid}`] = employeeInfo;
          return employeeInfo;
        }
      });
      pids = null;
      return res;
    };
    const filter = useArrToTree(data);
    treeData.value = treeFilter(filter);
    employeeData.value = employeeList.reduce((acc, item) => {
      const order = findIndex(acc, { id: item.id });
      if (order === -1) {
        acc.push(item);
      } else {
        acc[order].parentIds = [...acc[order].parentIds, ...item.parentIds];
      }
      return acc;
    }, []);
    deptData.value = data.filter(res => res.type === 1)?.map((res: TEmployeeDeptData) => {
      return {
        ...res,
        renderType: ERenderType[res?.type] as TRenderType,
        key: res.id,
      }
    });
  };

  return {
    treeData,
    deptData,
    letterData,
    employeeData,
    homeStaffData,
    onGetRenderData,
    onGetDepartmentData,
    onGetSubEmployeeData,
    onEmployeeDataAddAllDept,
    onEmployeeDataAddTopFive,
  };
};

export default useEmployeeData;
