/*
 * @Author: wfl
 * @LastEditors: wfl
 * @description:
 * @updateInfo:
 * @Date: 2022-08-10 19:46:41
 * @LastEditTime: 2022-10-14 09:35:09
 */
import { getAllMenu } from '@/mainApp/api/sys-default/menu';
import { MenuBtnEnum } from '@/global/enums/menuEnum';
import { useMessage } from '@/global/hooks/web/useMessage';
import { Checkbox, Skeleton, Table } from 'ant-design-vue';
import { ikTree } from 'iking-utils';
import { defineComponent, reactive, ref, toRef, watch } from 'vue';
import { RoleFormState } from '../type';

import roleApi from '@/mainApp/api/sys-default/role';
import type { MenuFormState } from '../type';
import { useRoleHook } from './useRoleHook';

interface RoleMenuTableProps extends MenuFormState {
  checked?: boolean;
  indeterminate?: boolean;
}

enum CheckEnum {
  CHECKED = 'CHECKED',
  UNCHECKED = 'UNCHECKED',
  PARTIAL_CHECKED = 'PARTIAL_CHECKED',
}

const RoleListComfig = defineComponent({
  props: {
    role: {
      type: Object as PropType<RoleFormState>,
    },
    helpState: {
      type: Boolean,
      default: false,
    },
    height: { type: Number, default: 0 },
  },
  emits: ['update'],
  setup(props) {
    const tableKeys = [
      {
        title: '菜单',
        dataIndex: 'name',
        resizable: true,
        width: 400,
      },
      {
        title: '操作',
        dataIndex: 'btn',
        resizable: true,
        width: 800,
      },
    ];
    const { createMessage } = useMessage();
    const loading = ref(false);
    const state: {
      [key: string]: RoleMenuTableProps[];
    } = reactive({
      menuTree: [],
      roleList: [],
      btnList: [],
      __menuList: [],
    });

    watch(
      () => props.role,
      (val) => {
        if (val?.id) {
          getMenuTreeData();
        }
      },
    );
    const { handChangeCheck, deepSetList } = useRoleHook(toRef(state, 'menuTree'));

    const getMenuTreeData = async () => {
      loading.value = true;
      state.btnList = [];
      try {
        const roleData = await roleApi.getRoleMenus(props.role?.id);
        const roleMenuList = roleData?.data?.roleMenuList || [];
        getMenuListData(roleMenuList);
      } catch (error) {
        loading.value = false;
        getMenuListData([]);
      }
    };

    const getMenuListData = async (roleMenuList) => {
      getAllMenu()
        .then(async ({ success, data, msg }) => {
          if (success) {
            state.__menuList = data;
            state.btnList = data.filter((item) =>
              [MenuBtnEnum.PAGE_BUTTON, MenuBtnEnum.GLOBAL_BUTTON].includes(item.menuType),
            );
            state.menuTree = ikTree.listToTree(
              data.map((item) => {
                const checkData = roleMenuList.find((it) => it.menuId === item.id);
                if (checkData) {
                  item.checked = checkData.checkStatus === CheckEnum.CHECKED ? true : false;
                  item.indeterminate =
                    checkData.checkStatus === CheckEnum.PARTIAL_CHECKED ? true : false;
                } else {
                  item.checked = false;
                  item.indeterminate = false;
                }
                return item;
              }),
            );
            await deepSetBtnChild(state.menuTree);
          } else {
            createMessage.warning(msg);
          }
          loading.value = false;
        })
        .catch(() => {
          loading.value = false;
        });
    };

    // 按钮绑定在__children属性上
    const deepSetBtnChild = (data) => {
      data.forEach((item) => {
        if (item?.children?.length) {
          if (
            [MenuBtnEnum.PAGE_BUTTON, MenuBtnEnum.GLOBAL_BUTTON].includes(item.children[0].menuType)
          ) {
            item.__children = item.children;
            delete item.children;
          } else {
            deepSetBtnChild(item.children);
          }
        }
      });
    };

    watch(
      () => props.helpState,
      () => {
        handSaveRoles();
      },
    );
    const handSaveRoles = async () => {
      loading.value = true;
      const deepTree = deepSetList(state.menuTree);
      const { msg } = await roleApi.updateRoleMenus({
        roleId: props.role?.id,
        menuIdList: deepTree
          .filter((item) => item.checked || item.indeterminate)
          .map((item) => item.id),
        roleMenuList: deepTree
          .filter((item) => item.checked || item.indeterminate)
          .map((item) => {
            return {
              id: item.id,
              menuId: item.id,
              checkStatus: item.checked
                ? CheckEnum.CHECKED
                : item.indeterminate
                ? CheckEnum.PARTIAL_CHECKED
                : CheckEnum.UNCHECKED,
            };
          }),
      });
      createMessage.success(msg);
      loading.value = false;
    };

    return () =>
      state.menuTree.length ? (
        <>
          <Table
            size="middle"
            indentSize={35}
            loading={loading.value}
            bordered
            sticky
            rowKey={(record) => record.__nodekey}
            defaultExpandAllRows
            pagination={false}
            columns={tableKeys}
            dataSource={state.menuTree || []}
            scroll={{
              scrollToFirstRowOnChange: true,
              y: props.height - 100,
            }}
          >
            {{
              headerCell: ({ column }) => {
                return column.dataIndex === 'btn' ? (
                  <div className="flex items-center justify-between">
                    <span>{column.title}</span>
                  </div>
                ) : (
                  <>{column.title}</>
                );
              },
              bodyCell: ({ column, record }) => {
                return (
                  <>
                    {record.menuType === MenuBtnEnum.MENU && column.dataIndex === 'name' ? (
                      <Checkbox
                        indeterminate={record.indeterminate}
                        v-model:checked={record.checked}
                        onChange={() => handChangeCheck(record)}
                      >
                        {record.name}
                      </Checkbox>
                    ) : column.dataIndex === 'btn' ? (
                      record?.__children?.map((item) => {
                        return (
                          <div className="w-110px inline-block">
                            <Checkbox
                              v-model:checked={item.checked}
                              onChange={() => handChangeCheck(item)}
                            >
                              {item.name}
                            </Checkbox>
                          </div>
                        );
                      })
                    ) : null}
                  </>
                );
              },
            }}
          </Table>
        </>
      ) : (
        <>
          <Skeleton active />
          <Skeleton active />
        </>
      );
  },
});

export default RoleListComfig;
