<template>
  <div>
    <a-card class="general-card" style="min-height: 75vh">
      <template #title>
        <a-space>
          <a-typography-text style="font-weight: bolder; margin: 0 80px 0 10px"
            >角色详情</a-typography-text
          >

          <a-typography-text style="margin-right: 10px"
            >角色ID：</a-typography-text
          >
          <a-typography-text type="primary" style="margin-right: 50px">
            {{ selectRoleId }}
          </a-typography-text>
          <a-typography-text style="margin-right: 10px"
            >角色名称：</a-typography-text
          >
          <a-typography-text type="primary">
            {{ selectRoleName }}
          </a-typography-text>
        </a-space>
      </template>
      <a-divider style="margin-top: 6px; margin-bottom: 0" />
      <a-tabs
        v-model:active-key="selectedTab"
        size="large"
        class="role-tabs"
        @change="changeRoleTabs"
      >
        <a-tab-pane :key="RoleTabs[0]" title="权限分配">
          <a-row style="flex-flow: nowrap">
            <a-col
              flex="350px"
              style="border-right: 2px dashed rgba(0, 0, 0, 0.06)"
            >
              <a-scrollbar style="height: 75vh; overflow-y: auto">
                <a-tree
                  ref="moduleTreeRef"
                  class="dtree"
                  size="large"
                  :field-names="{
                    key: 'id',
                    title: 'name'
                  }"
                  default-expand-all
                  :data="moduleTree"
                  :block-node="true"
                  @select="handleNodeClick"
                >
                </a-tree>
              </a-scrollbar>
            </a-col>
            <a-col flex="auto">
              <a-table
                v-model:selected-keys="selectKeys"
                :row-selection="rowSelection"
                :pagination="false"
                :columns="tableColumns"
                :data="funList"
                :bordered="{
                  cell: false,
                  headerCell: true,
                  wrapper: false
                }"
                :hoverable="false"
                row-key="id"
                table-layout-fixed
                @selection-change="handleSelectionChange($event as number[])"
              >
              </a-table>
            </a-col>
          </a-row>
        </a-tab-pane>
        <a-tab-pane :key="RoleTabs[1]" title="资源分配"> 资源分配 </a-tab-pane>
      </a-tabs>
    </a-card>
  </div>
</template>

<!-- @select="handleNodeClick" -->
<script lang="ts" setup>
import { ref, reactive, onMounted, h } from 'vue'
import { ModuleTreeResParams, ModuleTree } from '@/types/module'
import { getFuncGroupTree, getRoleFun, setRoleFun } from '@/api/acs/role'
import { IconFile, IconFolder } from '@arco-design/web-vue/es/icon'
import {
  Message,
  TableColumnData,
  TableRowSelection
} from '@arco-design/web-vue'
import { RoleFunResParams, Func } from '@/types/role'
import { useEmitt } from '@/logics/mitt/useEmitt'

enum RoleTabs {
  'authority',
  'resources'
}

const rowSelection = reactive<TableRowSelection>({
  type: 'checkbox',
  showCheckedAll: true,
  onlyCurrent: false
})

const selectedTab = ref<string>(RoleTabs[0])
const moduleTreeRef = ref<any>() // 模块树ref
const moduleTree = ref<ModuleTree[]>([]) // 模块树
const funList = ref<Func[]>([]) // 角色列表
const selectKeys = ref<number[]>([])
const selectRoleId = ref<string>()
const selectRoleName = ref<string>()
const selectModuleId = ref<number>()

// checkbox发生改变时，更新store数据
const handleSelectionChange = async (rowKeys: number[]) => {
  selectKeys.value = rowKeys
  const funcs: { id: number; enabled: boolean }[] = []
  funList.value = funList.value.map(item => {
    if (selectKeys.value.includes(item.id) && !item.enabled) {
      funcs.push({
        id: item.id,
        enabled: true
      })
      item.enabled = true
    }
    if (!selectKeys.value.includes(item.id) && item.enabled) {
      funcs.push({
        id: item.id,
        enabled: false
      })
      item.enabled = false
    }
    return item
  })
  await setRoleFun(selectRoleId.value!, funcs)
  Message.success('设置成功！')
}

/**
 * 递归获取ng-tree需要的结构体
 * @param modules 接口返回的树状数组
 */
const getNodesTree = (modules: ModuleTree): ModuleTree => {
  modules.key = modules.id.toString()
  modules.title = modules.name
  if (modules.children && modules.children.length > 0) {
    modules.children.map(res => getNodesTree(res))
    modules.icon = () =>
      h(IconFolder, {
        size: 20
      })
  } else {
    modules.icon = () =>
      h(IconFile, {
        size: 20
      })
  }
  return modules
}

/**
 * 获取域树
 */
const getTree = async () => {
  const { tree }: ModuleTreeResParams = await getFuncGroupTree()
  moduleTree.value = tree.map(modules => {
    return getNodesTree(modules)
  })
}

const changeRoleTabs = async (key: string | number) => {
  if (key === RoleTabs[0]) {
    await getTree()
    moduleTreeRef.value.expandAll()
  }
}

const tableColumns: TableColumnData[] = [
  {
    title: '名称',
    dataIndex: 'name',
    align: 'left'
  },
  {
    title: '标识',
    dataIndex: 'api',
    align: 'left'
  },
  {
    title: '备注',
    dataIndex: 'memo',
    align: 'left'
  }
]

/**
 * 域树节点点击事件
 * @param newSelectkedKeys 已选择树节点key，数组。
 * @param data 选中树节点对应的data
 */
const handleNodeClick = async (
  _newSelectkedKeys: (string | number)[],
  data: any
) => {
  const { node } = data
  selectModuleId.value = node.id
  getRoleFunList(node.id)
}

const getRoleFunList = async (moduleId: number) => {
  selectKeys.value = []
  const { funcs }: RoleFunResParams = await getRoleFun(
    selectRoleId.value!,
    moduleId
  )
  funcs.forEach(item => {
    if (item.enabled) {
      selectKeys.value.push(item.id)
    }
  })
  funList.value = funcs
}

// 监听子组件增加，修改，删除事件，更新列表
useEmitt({
  name: 'changeRole',
  callback: ({ id, name }) => {
    selectRoleId.value = id
    selectRoleName.value = name
    if (selectModuleId.value) {
      getRoleFunList(selectModuleId.value)
    }
  }
})

onMounted(() => {
  changeRoleTabs(RoleTabs[0])
})
</script>

<script lang="ts">
export default {
  name: 'RoleContent'
}
</script>

<style scoped lang="less">
.role-tabs {
  :deep(.arco-tabs-tab) {
    margin: 0 30px;
  }
}
.dtree {
  padding: 0 10px;
  // max-height: 350px;
  :deep(.arco-tree-node-selected) {
    background-color: rgb(var(--gray-2));
  }
  :deep(.arco-tree-node:hover) {
    background-color: rgb(var(--gray-2));
  }
  :deep(.arco-tree-node-title:hover) {
    background-color: transparent;
  }
}
</style>

<!-- .arco-tabs-nav-type-line .arco-tabs-tab -->
