<script setup lang="ts">
import { onMounted, ref, useTemplateRef, watch } from 'vue';

import ConfirmModal from '@/components/ConfirmModal.vue';
import SvgIcon from '@/components/SvgIcon.vue';
import { useRequest } from '@/hooks/request';
import { t } from '@/i18n';
import {
  addRolePermissions,
  addUpdateRolePermissions,
  deleteCharacter,
  getFindRolesByOrgIds,
  getRolePermissions,
  getSubPermList,
} from '@/api';

import type { TreeProps } from 'ant-design-vue';
import type { Rule } from 'ant-design-vue/es/form';
import type { DataNode } from 'ant-design-vue/es/tree';
import type { CharacterForm, CharacterPageItem, CreateCustomer, TreeStructure, UseGuideStepItemProps } from '@/types';

const rules: Record<string, Rule[]> = {
  name: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
};

const { handleRequest } = useRequest();
const modalComponentRef = useTemplateRef('modalComponent');
const characterList = ref<CharacterPageItem[]>([]);
const characterOpen = ref<boolean>(false);
const characterTitle = ref<boolean>(true);
const checked = ref<boolean>(false);
const checkedAll = ref<number[]>([]);
const indeterminate = ref<boolean>(false);
const characterId = ref<number>(0);
const expandedKeys = ref<number[]>([]);
const selectedKeys = ref<number[]>([]);
const checkedKeys = ref<number[]>([]);

const fieldNames: TreeProps['fieldNames'] = {
  children: 'subPermissions',
  title: 'menuName',
  key: 'id',
};
const props = defineProps<UseGuideStepItemProps<CreateCustomer>>();
const treeStructure = ref<DataNode[]>([]);
const characterForm = ref<CharacterForm>({
  roleName: '',
  remark: '',
});
const handleClose = () => {
  characterForm.value.roleName = '';
  characterForm.value.remark = '';
  checkedKeys.value = [];
  indeterminate.value = false;
  checked.value = false;
  expandedKeys.value = [];
};
const addCharacter = () => {
  characterTitle.value = true;
  characterOpen.value = true;
};
const characterSave = () => {
  handleRequest(async () => {
    if (characterTitle.value) {
      await addRolePermissions({
        ...characterForm.value,
        orgId: props.form.id as number,
        enabled: '1',
        permissionIds: checkedKeys.value,
      });
    } else {
      await addUpdateRolePermissions({
        id: characterId.value,
        ...characterForm.value,
        orgId: props.form.id as number,
        enabled: '1',
        permissionIds: checkedKeys.value,
      });
    }

    getFindRolesByOrg();
    characterOpen.value = false;
  });
};
const cancelSave = () => {
  checkedKeys.value = [];
  characterOpen.value = false;
};
const confirm = () => {
  handleRequest(async () => {
    await deleteCharacter(characterId.value);
    getFindRolesByOrg();
    modalComponentRef.value?.hideView();
  });
};
const characterEditor = (id: number) => {
  characterId.value = id;
  characterTitle.value = false;
  characterOpen.value = true;
  handleRequest(async () => {
    const { remark, roleName, permissionCheckTreeVos } = await getRolePermissions(id);
    checkedKeys.value = [];
    characterForm.value.roleName = roleName;
    characterForm.value.remark = remark;

    permissionCheckTreeVos[0].subPermissions[0].subPermissions.forEach((item) => {
      if (item.subPermissions) {
        item.subPermissions.forEach((i) => {
          if (i.checked === 1) {
            checkedKeys.value.push(i.id);
          }
        });
        expandedKeys.value.push(item.id);
      } else {
        if (item.checked === 1) {
          checkedKeys.value.push(item.id);
        }
      }
    });
  });
};
const characterDelete = (id: number) => {
  characterId.value = id;
  modalComponentRef.value?.showView();
};

const selectAll = () => {
  indeterminate.value = false;
  if (checked.value) {
    checkedKeys.value = checkedAll.value;
  } else {
    checkedKeys.value = [];
  }
};

// 获取所有节点 key 的递归方法
const getAllKeys = (data: DataNode[]) => {
  let keys: number[] = [];
  data.forEach((item) => {
    keys.push(item.id);
    expandedKeys.value.push(item.id);
    if (item.subPermissions) {
      keys = keys.concat(getAllKeys(item.subPermissions));
    }
  });
  return keys;
};

const transformTreeData = (data: TreeStructure[]): DataNode[] => {
  return data.map((item) => ({
    ...item,
    key: item.id, // 关键：将 id 映射到 key
    title: item.menuName,
    children: item.subPermissions ? transformTreeData(item.subPermissions) : undefined,
  }));
};

const getFindRolesByOrg = () => {
  handleRequest(async () => {
    if (props.form.id) {
      characterList.value = [];
      const list = await getFindRolesByOrgIds([props.form.id]);
      list.forEach((item) => {
        if (item.roleName !== '管理员' && item.roleName !== '工程师') {
          characterList.value.push(item);
        }
      });
    }
  });
};

watch(
  () => checkedKeys.value,
  (count) => {
    if (count) {
      indeterminate.value = !!count.length && count.length < checkedAll.value.length;
      checked.value = count.length === checkedAll.value.length;
    }
  },
);

onMounted(() => {
  handleRequest(async () => {
    getFindRolesByOrg();
    const data = await getSubPermList(0);

    treeStructure.value = transformTreeData(data[0].subPermissions[0].subPermissions);
    checkedAll.value = getAllKeys(treeStructure.value);
  });
});
</script>

<template>
  <div>
    <div class="character"><span class="character-text">*</span>创建角色</div>
    <AFlex :vertical="true" :gap="16">
      <AFlex align="center">
        <AFlex class="input-style" align="center"> 管理员 </AFlex>
        <div class="input-style-text">默认角色</div>
      </AFlex>
      <AFlex align="center">
        <AFlex class="input-style" align="center"> 运维人员 </AFlex>
        <div class="input-style-text">默认角色</div>
      </AFlex>
      <AFlex align="center" v-for="(item, index) in characterList" :key="index">
        <AFlex class="input-style input-background" align="center"> {{ item.roleName }} </AFlex>
        <div @click="characterEditor(item.id)">
          <AFlex class="editorial-role" align="center" justify="center">
            <SvgIcon name="edit-o" />
          </AFlex>
        </div>
        <div @click="characterDelete(item.id)">
          <AFlex class="editorial-role" align="center" justify="center">
            <SvgIcon class="icon-color" name="delete" />
          </AFlex>
        </div>
      </AFlex>
    </AFlex>
    <AButton type="primary" ghost class="icon-button button-style" @click="addCharacter">
      <AFlex align="center">
        <SvgIcon name="plus" />
        <span> 增加角色 </span>
      </AFlex>
    </AButton>
    <AModal
      v-model:open="characterOpen"
      :title="characterTitle ? '添加角色' : '编辑角色'"
      width="920px"
      :mask-closable="false"
      :footer="null"
      :after-close="handleClose"
    >
      <AForm
        ref="formRef"
        class="alarm-modal"
        :model="characterForm"
        label-align="left"
        :rules="rules"
        :label-col="{ span: 3 }"
      >
        <AFormItem label="角色名称" name="roleName">
          <AInput class="input-width" v-model:value="characterForm.roleName" placeholder="请输入角色名称" />
        </AFormItem>
        <AFormItem label="角色描述">
          <ATextarea
            class="input-width"
            v-model:value="characterForm.remark"
            :placeholder="t('common.pleaseEnter')"
            :auto-size="{ minRows: 4 }"
          />
        </AFormItem>
        <AFormItem label="菜单权限配置">
          <div class="permission-configuration">
            <ACheckbox class="select-all" :indeterminate="indeterminate" v-model:checked="checked" @change="selectAll"
              >全选</ACheckbox
            >
            <ATree
              v-model:expanded-keys="expandedKeys"
              v-model:selected-keys="selectedKeys"
              v-model:checked-keys="checkedKeys"
              :tree-data="treeStructure"
              checkable
              :field-names="fieldNames"
            />
          </div>
        </AFormItem>
      </AForm>
      <AFlex justify="flex-end" class="footer">
        <AButton class="button-right" type="primary" ghost @click="cancelSave">{{ $t('common.cancel') }}</AButton>
        <AButton type="primary" @click="characterSave">保存</AButton>
      </AFlex>
    </AModal>
    <ConfirmModal
      ref="modalComponent"
      :title="t('common.deleteConfirmation')"
      :description-text="t('common.confirmDeletion')"
      :icon="{ name: 'delete' }"
      :icon-bg-color="'#F56C6C'"
      @confirm="confirm"
    />
  </div>
</template>

<style lang="scss" scoped>
.select-all {
  margin-bottom: 12px;
  margin-left: 10px;
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  line-height: 24px;
  color: #000;
  text-align: left;
}

.permission-configuration {
  width: 772px;
  height: 294px;
  padding: 16px 14px 24px;
  overflow: auto;
  background: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
}

.input-width {
  width: 328px;
}

.button-right {
  margin-right: 16px;
}

.button-style {
  margin-top: 24px;
}

.icon-color {
  color: #f67f7f;
}

.editorial-role {
  width: 32px;
  height: 32px;
  margin-right: 12px;
  cursor: pointer;
  background: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
}

.character {
  margin-bottom: 16px;
  color: rgb(0 0 0 / 85%);
}

.input-style-text {
  font-size: 12px;
  font-style: normal;
  font-weight: 400;
  line-height: 22px;
  color: #666;
  text-align: left;
}

.input-style {
  width: 256px;
  height: 32px;
  padding-left: 12px;
  margin-right: 16px;
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  line-height: 22px;
  color: #333;
  text-align: left;
  background: #f5f7fa;
  border: 1px solid rgb(0 0 0 / 15%);
  border-radius: 4px;
}

.input-background {
  background: #fff;
}

.character-text {
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  line-height: 22px;
  color: #e02020;
  text-align: left;
}
</style>
