<template>
  <ArtTableFullScreen>
    <div class="role-page" id="table-full-screen">
      <!-- 搜索栏 -->
      <ArtSearchBar
        v-model:filter="searchForm"
        :items="searchFormItems"
        :show-expand="false"
        @reset="handleReset"
        @search="handleSearch"
      ></ArtSearchBar>

      <ElCard shadow="never" class="art-table-card">
        <!-- 表格头部 -->
        <ArtTableHeader
          :columnList="columnOptions"
          v-model:columns="columnChecks"
          @refresh="handleRefresh"
        >
          <template #left>
            <ElButton @click="showDialog('add')" v-permission="'role:add'">新增角色</ElButton>
          </template>
        </ArtTableHeader>

        <!-- 表格 -->
        <ArtTable
          ref="tableRef"
          row-key="ID"
          :loading="loading"
          :data="roleList"
          :currentPage="pagination.page"
          :pageSize="pagination.pageSize"
          :total="pagination.total"
          :marginTop="10"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        >
          <template #default>
            <ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
          </template>
        </ArtTable>

        <!-- 新增/编辑对话框 -->
        <ElDialog
          v-model="dialogVisible"
          :title="dialogType === 'add' ? '新增角色' : '编辑角色'"
          width="30%"
        >
          <ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
            <ElFormItem label="角色名称" prop="role_name">
              <ElInput v-model="form.role_name" placeholder="请输入角色名称" />
            </ElFormItem>
            <ElFormItem label="角色描述" prop="role_desc">
              <ElInput
                v-model="form.role_desc"
                type="textarea"
                :rows="3"
                placeholder="请输入角色描述"
              />
            </ElFormItem>
            <ElFormItem label="角色类型" prop="role_type">
              <ElSelect
                v-model="form.role_type"
                placeholder="请选择角色类型"
                style="width: 100%"
                :disabled="dialogType === 'edit'"
              >
                <ElOption
                  v-for="item in ROLE_TYPE_OPTIONS"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="状态">
              <ElSwitch
                v-model="form.status"
                :active-value="CommonStatus.ENABLED"
                :inactive-value="CommonStatus.DISABLED"
              />
            </ElFormItem>
            <template v-if="isCustomerRoleForm">
              <ElFormItem label="新建代理默认信用">
                <ElSwitch
                  v-model="form.credit_enabled"
                  @change="handleDefaultCreditEnabledChange"
                />
              </ElFormItem>
              <ElFormItem label="默认信用额度">
                <ElInputNumber
                  v-model="form.credit_limit_yuan"
                  :disabled="!form.credit_enabled"
                  :min="0"
                  :precision="2"
                  :step="100"
                  controls-position="right"
                  style="width: 100%"
                  placeholder="请输入默认信用额度"
                />
                <div class="credit-form-tip">单位：元。修改后不会影响已有店铺</div>
              </ElFormItem>
            </template>
          </ElForm>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="dialogVisible = false">取消</ElButton>
              <ElButton type="primary" @click="handleSubmit(formRef)" :loading="submitLoading">
                提交
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 分配权限对话框 -->
        <ElDialog v-model="permissionDialogVisible" width="60%">
          <template #header>
            <div class="dialog-header">
              <span class="dialog-title">分配权限</span>
              <div class="role-info">
                <ElTag :type="currentRole.role_type === 1 ? 'primary' : 'success'" size="small">
                  {{ currentRole.role_type === 1 ? '平台角色' : '客户角色' }}
                </ElTag>
                <span class="role-name">{{ currentRole.role_name }}</span>
              </div>
            </div>
          </template>
          <div class="permission-tree-transfer-container">
            <!-- 左侧：可分配权限树 -->
            <div class="transfer-panel">
              <div class="panel-header">
                <span class="panel-title">可分配权限</span>
                <ElInput
                  v-model="leftTreeFilter"
                  placeholder="搜索权限"
                  clearable
                  size="small"
                  style="width: 180px"
                />
              </div>
              <div class="panel-body">
                <ElTree
                  ref="leftTreeRef"
                  :data="availablePermissions"
                  :props="{ children: 'children', label: 'label' }"
                  node-key="id"
                  show-checkbox
                  check-strictly
                  :filter-node-method="filterNode"
                  :default-expand-all="false"
                  :check-on-click-node="false"
                  @check="handleLeftTreeCheck"
                  class="permission-tree"
                >
                  <template #default="{ node, data }">
                    <span style="display: flex; gap: 8px; align-items: center">
                      <span>{{ node.label }}</span>
                      <ElTag :type="data.perm_type === 1 ? 'info' : 'success'" size="small">
                        {{ data.perm_type === 1 ? '菜单' : '按钮' }}
                      </ElTag>
                    </span>
                  </template>
                </ElTree>
              </div>
            </div>

            <!-- 中间：操作按钮 -->
            <div class="transfer-buttons">
              <ElButton
                type="primary"
                :icon="'ArrowRight'"
                @click="addPermissions"
                :disabled="getLeftCheckedKeys().length === 0"
                :loading="addingPermissionLoading"
              >
                添加
              </ElButton>
            </div>

            <!-- 右侧：已分配权限树 -->
            <div class="transfer-panel">
              <div class="panel-header">
                <span class="panel-title">已分配权限</span>
                <ElInput
                  v-model="rightTreeFilter"
                  placeholder="搜索权限"
                  clearable
                  size="small"
                  style="width: 180px"
                />
              </div>
              <div class="panel-body">
                <ElTree
                  ref="rightTreeRef"
                  :data="assignedPermissions"
                  :props="{ children: 'children', label: 'label' }"
                  node-key="id"
                  :filter-node-method="filterNode"
                  :default-expand-all="false"
                  class="permission-tree permission-tree-with-action"
                >
                  <template #default="{ node, data }">
                    <span class="tree-node-content">
                      <span class="tree-node-label">
                        <span>{{ node.label }}</span>
                        <ElTag :type="data.perm_type === 1 ? 'info' : 'success'" size="small">
                          {{ data.perm_type === 1 ? '菜单' : '按钮' }}
                        </ElTag>
                      </span>
                      <ElButton
                        type="danger"
                        size="small"
                        link
                        @click="removeSinglePermission(data)"
                      >
                        移除
                      </ElButton>
                    </span>
                  </template>
                </ElTree>
              </div>
            </div>
          </div>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="permissionDialogVisible = false">关闭</ElButton>
            </div>
          </template>
        </ElDialog>
      </ElCard>
    </div>
  </ArtTableFullScreen>
</template>

<script setup lang="ts">
  import { h } from 'vue'
  import { RoleService, PermissionService } from '@/api/modules'
  import {
    ElMessage,
    ElMessageBox,
    ElTag,
    ElTree,
    ElSwitch,
    ElButton,
    ElInput,
    ElSelect,
    ElOption
  } from 'element-plus'
  import type { FormInstance, FormRules } from 'element-plus'
  import { RoleType } from '@/types/api'
  import type { PlatformRole, PermissionTreeNode } from '@/types/api'
  import type { SearchFormItem } from '@/types'
  import { useCheckedColumns } from '@/composables/useCheckedColumns'
  import { useAuth } from '@/composables/useAuth'
  import { fenToYuan, formatDateTime, yuanToFen } from '@/utils/business/format'
  import {
    CommonStatus,
    getStatusText,
    ROLE_TYPE_OPTIONS,
    getRoleTypeLabel
  } from '@/config/constants'

  defineOptions({ name: 'Role' })

  const { hasAuth } = useAuth()
  const canUpdateRoleStatus = hasAuth('role:update_status')

  const dialogVisible = ref(false)
  const permissionDialogVisible = ref(false)
  const loading = ref(false)
  const submitLoading = ref(false)
  const addingPermissionLoading = ref(false)
  const tableRef = ref()
  const leftTreeRef = ref()
  const rightTreeRef = ref()
  const currentRoleId = ref<number>(0)
  const currentRole = ref<{ role_name: string; role_type: number }>({
    role_name: '',
    role_type: 1
  })
  const selectedPermissions = ref<number[]>([])
  const originalPermissions = ref<number[]>([]) // 保存原始权限，用于对比
  const availablePermissions = ref<any[]>([]) // 左侧可分配权限树数据
  const assignedPermissions = ref<any[]>([]) // 右侧已分配权限树数据
  const allPermissionsMap = ref<Map<number, any>>(new Map()) // 所有权限的映射表
  const leftTreeFilter = ref('') // 左侧树搜索关键字
  const rightTreeFilter = ref('') // 右侧树搜索关键字
  const isHandlingCheck = ref(false) // 标志位:是否正在处理勾选事件

  // 搜索表单初始值
  const initialSearchState = {
    role_name: '',
    role_type: undefined as number | undefined,
    status: undefined as number | undefined
  }

  // 搜索表单
  const searchForm = reactive({ ...initialSearchState })

  // 搜索表单配置
  const searchFormItems: SearchFormItem[] = [
    {
      label: '角色名称',
      prop: 'role_name',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入角色名称'
      }
    },
    {
      label: '角色类型',
      prop: 'role_type',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '请选择角色类型'
      },
      options: () => ROLE_TYPE_OPTIONS
    },
    {
      label: '状态',
      prop: 'status',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '请选择状态'
      },
      options: () => [
        { label: '启用', value: 1 },
        { label: '禁用', value: 0 }
      ]
    }
  ]

  // 分页
  const pagination = reactive({
    page: 1,
    pageSize: 20,
    total: 0
  })

  // 列配置
  const columnOptions = [
    { label: '角色名称', prop: 'role_name' },
    { label: '角色描述', prop: 'role_desc' },
    { label: '角色类型', prop: 'role_type' },
    ...(canUpdateRoleStatus ? [{ label: '状态', prop: 'status' }] : []),
    { label: '创建时间', prop: 'CreatedAt' }
  ]

  const formRef = ref<FormInstance>()

  const rules = reactive<FormRules>({
    role_name: [
      { required: true, message: '请输入角色名称', trigger: 'blur' },
      { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
    ],
    role_desc: [{ max: 200, message: '描述不能超过200个字符', trigger: 'blur' }],
    role_type: [{ required: true, message: '请选择角色类型', trigger: 'change' }]
  })

  const form = reactive<any>({
    id: 0,
    role_name: '',
    role_desc: '',
    role_type: 1,
    status: CommonStatus.ENABLED,
    credit_enabled: false,
    credit_limit_yuan: 0
  })

  const isCustomerRoleForm = computed(() => form.role_type === RoleType.CUSTOMER)

  const handleDefaultCreditEnabledChange = (enabled: boolean | string | number) => {
    if (!enabled) {
      form.credit_limit_yuan = 0
    }
  }

  const getDefaultCreditPayload = () => {
    const creditEnabled = Boolean(form.credit_enabled)
    return {
      credit_enabled: creditEnabled,
      credit_limit: creditEnabled ? yuanToFen(form.credit_limit_yuan) || 0 : 0
    }
  }

  const roleList = ref<PlatformRole[]>([])

  // 动态列配置
  const { columnChecks, columns } = useCheckedColumns(() => [
    {
      prop: 'role_name',
      label: '角色名称',
      width: 180
    },
    {
      prop: 'role_type',
      label: '角色类型',
      width: 100,
      formatter: (row: any) => {
        return h(ElTag, { type: row.role_type === 1 ? 'primary' : 'success' }, () =>
          getRoleTypeLabel(row.role_type)
        )
      }
    },
    ...(canUpdateRoleStatus
      ? [
          {
            prop: 'status',
            label: '状态',
            width: 100,
            formatter: (row: any) => {
              return h(ElSwitch, {
                modelValue: row.status,
                activeValue: CommonStatus.ENABLED,
                inactiveValue: CommonStatus.DISABLED,
                activeText: getStatusText(CommonStatus.ENABLED),
                inactiveText: getStatusText(CommonStatus.DISABLED),
                inlinePrompt: true,
                'onUpdate:modelValue': (val: string | number | boolean) =>
                  handleStatusChange(row, val as number)
              })
            }
          }
        ]
      : []),
    {
      prop: 'role_desc',
      label: '角色描述'
    },
    {
      prop: 'CreatedAt',
      label: '创建时间',
      width: 180,
      formatter: (row: any) => formatDateTime(row.CreatedAt)
    },
    {
      prop: 'actions',
      label: '操作',
      width: 220,
      fixed: 'right',
      formatter: (row: any) => {
        const buttons: any[] = []

        if (hasAuth('role:permission')) {
          buttons.push(
            h(
              ElButton,
              {
                type: 'warning',
                link: true,
                onClick: () => showPermissionDialog(row)
              },
              () => '分配权限'
            )
          )
        }

        if (hasAuth('role:edit')) {
          buttons.push(
            h(
              ElButton,
              {
                type: 'primary',
                link: true,
                onClick: () => showDialog('edit', row)
              },
              () => '编辑'
            )
          )
        }

        if (hasAuth('role:delete')) {
          buttons.push(
            h(
              ElButton,
              {
                type: 'danger',
                link: true,
                onClick: () => deleteRole(row)
              },
              () => '删除'
            )
          )
        }

        return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
      }
    }
  ])

  onMounted(() => {
    getTableData()
  })

  // 监听搜索关键字变化
  watch(leftTreeFilter, (val) => {
    leftTreeRef.value?.filter(val)
  })

  watch(rightTreeFilter, (val) => {
    rightTreeRef.value?.filter(val)
  })

  // 树节点过滤方法
  const filterNode = (value: string, data: any) => {
    if (!value) return true
    return data.label.toLowerCase().includes(value.toLowerCase())
  }

  // 更新父节点的勾选状态(计算应该半选的父节点)
  const updateParentCheckStatus = (checkedKeys: number[]) => {
    const checkedSet = new Set(checkedKeys)
    const parentIdsToHalfCheck = new Set<number>()

    // 递归检查节点的子节点勾选状态
    const checkNode = (node: any): { allChecked: boolean; someChecked: boolean } => {
      if (!node.children || node.children.length === 0) {
        // 叶子节点
        return {
          allChecked: checkedSet.has(node.id),
          someChecked: checkedSet.has(node.id)
        }
      }

      // 有子节点的节点
      let allChecked = true
      let someChecked = false

      for (const child of node.children) {
        const childStatus = checkNode(child)
        if (!childStatus.allChecked) {
          allChecked = false
        }
        if (childStatus.someChecked) {
          someChecked = true
        }
      }

      // 当前节点被勾选
      const currentNodeChecked = checkedSet.has(node.id)

      // 判断父节点应该显示的状态:
      // 1. 如果当前节点被勾选，但不是所有子节点都被勾选 -> 半选
      // 2. 如果有子节点被勾选，但当前节点未被勾选 -> 半选
      // 3. 如果所有子节点都被勾选且当前节点也被勾选 -> 全选
      if (currentNodeChecked) {
        // 当前节点被勾选
        if (!allChecked) {
          // 但不是所有子节点都被勾选 -> 半选
          parentIdsToHalfCheck.add(node.id)
        }
        // 如果 allChecked，则为全选，不需要设置半选
      } else if (someChecked) {
        // 当前节点未勾选，但有子节点被勾选 -> 半选
        parentIdsToHalfCheck.add(node.id)
      }

      return {
        allChecked: allChecked && currentNodeChecked,
        someChecked: someChecked || currentNodeChecked
      }
    }

    // 检查所有顶层节点
    availablePermissions.value.forEach((node) => checkNode(node))

    return Array.from(parentIdsToHalfCheck)
  }

  // 判断节点是否为一级菜单（没有父节点或parent_id为0/null）
  const isFirstLevelMenu = (nodeId: number): boolean => {
    const node = allPermissionsMap.value.get(nodeId)
    if (!node) return false
    return !node.parent_id || node.parent_id === 0
  }

  // 获取节点的所有子节点ID（递归）
  const getAllChildrenIds = (nodeId: number): number[] => {
    const childrenIds: number[] = []

    const collectChildren = (id: number) => {
      const node = allPermissionsMap.value.get(id)
      if (!node || !node.children || node.children.length === 0) return

      node.children.forEach((child: any) => {
        childrenIds.push(child.id)
        collectChildren(child.id)
      })
    }

    collectChildren(nodeId)
    return childrenIds
  }

  // 上一次勾选的keys，用于判断是勾选还是取消勾选
  const previousCheckedKeys = ref<number[]>([])

  // 处理左侧树的勾选事件
  const handleLeftTreeCheck = (data: any, checked: any) => {
    if (isHandlingCheck.value) return

    isHandlingCheck.value = true

    try {
      // 获取当前勾选的keys
      let currentChecked = checked.checkedKeys as number[]

      // 判断是勾选还是取消勾选（通过对比当前和之前的keys）
      const isChecking =
        currentChecked.includes(data.id) && !previousCheckedKeys.value.includes(data.id)
      const isUnchecking =
        !currentChecked.includes(data.id) && previousCheckedKeys.value.includes(data.id)

      if (isChecking) {
        // 正在勾选节点
        // 判断当前节点是否为一级菜单
        if (isFirstLevelMenu(data.id)) {
          // 一级菜单：自动勾选所有子节点（包括所有子菜单和按钮）
          const childrenIds = getAllChildrenIds(data.id)
          const newCheckedKeys = [...new Set([...currentChecked, ...childrenIds])]

          // 设置新的勾选状态
          leftTreeRef.value?.setCheckedKeys(newCheckedKeys, false)
          currentChecked = newCheckedKeys
        } else {
          // 二级及以下菜单/按钮：只勾选自己，不勾选子节点
          const childrenIds = getAllChildrenIds(data.id)
          // 从当前勾选中移除所有子节点（如果有的话）
          const newCheckedKeys = currentChecked.filter((id) => !childrenIds.includes(id))

          // 设置新的勾选状态
          leftTreeRef.value?.setCheckedKeys(newCheckedKeys, false)
          currentChecked = newCheckedKeys
        }
      } else if (isUnchecking) {
        // 正在取消勾选节点
        // 判断当前节点是否为一级菜单
        if (isFirstLevelMenu(data.id)) {
          // 一级菜单：自动取消所有子节点（包括所有子菜单和按钮）
          const childrenIds = getAllChildrenIds(data.id)
          const newCheckedKeys = currentChecked.filter((id) => !childrenIds.includes(id))

          // 设置新的勾选状态
          leftTreeRef.value?.setCheckedKeys(newCheckedKeys, false)
          currentChecked = newCheckedKeys
        }
        // 二级及以下菜单/按钮：直接取消勾选，不需要额外处理
      }

      // 更新上一次勾选的keys
      previousCheckedKeys.value = [...currentChecked]

      // 计算应该半选的父节点
      const halfCheckedIds = updateParentCheckStatus(currentChecked)

      // 使用内部API直接操作树的半选状态
      nextTick(() => {
        if (leftTreeRef.value && leftTreeRef.value.store) {
          // 清除所有半选状态
          Object.values(leftTreeRef.value.store.nodesMap).forEach((node: any) => {
            node.indeterminate = false
          })

          // 设置应该半选的节点
          halfCheckedIds.forEach((id: number) => {
            const node = leftTreeRef.value.store.nodesMap[id]
            if (node) {
              node.indeterminate = true
            }
          })
        }
      })
    } finally {
      isHandlingCheck.value = false
    }
  }

  // 构建权限树数据结构（只包含启用的权限）
  const buildTreeData = (treeNodes: PermissionTreeNode[]): any[] => {
    return treeNodes
      .filter((node) => node.status === 1) // 只显示启用的权限
      .map((node) => ({
        id: node.id,
        label: node.perm_name,
        perm_type: node.perm_type,
        status: node.status ?? 1,
        children:
          node.children && node.children.length > 0 ? buildTreeData(node.children) : undefined
      }))
  }

  // 构建权限映射表（包括所有节点和子节点）
  const buildPermissionMap = (treeNodes: PermissionTreeNode[], map: Map<number, any>) => {
    treeNodes.forEach((node) => {
      map.set(node.id, node)
      if (node.children && node.children.length > 0) {
        buildPermissionMap(node.children, map)
      }
    })
  }

  // 根据权限ID列表过滤树节点（包含指定ID的节点）
  const filterTreeByIds = (treeNodes: any[], ids: number[]): any[] => {
    const result: any[] = []

    treeNodes.forEach((node) => {
      if (ids.includes(node.id)) {
        const newNode = { ...node }
        if (node.children && node.children.length > 0) {
          newNode.children = filterTreeByIds(node.children, ids)
        }
        result.push(newNode)
      } else if (node.children && node.children.length > 0) {
        const filteredChildren = filterTreeByIds(node.children, ids)
        if (filteredChildren.length > 0) {
          result.push({
            ...node,
            children: filteredChildren
          })
        }
      }
    })

    return result
  }

  // 根据权限ID列表设置树节点的禁用状态
  // 同时禁用状态为禁用(status=0)的权限
  const setTreeNodesDisabled = (treeNodes: any[], idsToDisable: number[]): any[] => {
    return treeNodes.map((node) => {
      const newNode = {
        ...node,
        // 如果已分配或状态为禁用,则禁用该节点
        disabled: idsToDisable.includes(node.id) || node.status === 0
      }

      if (node.children && node.children.length > 0) {
        newNode.children = setTreeNodesDisabled(node.children, idsToDisable)
      }

      return newNode
    })
  }

  // 保存原始权限树数据
  const originalPermissionTree = ref<PermissionTreeNode[]>([])

  // 加载所有权限树
  const loadAllPermissions = async () => {
    try {
      const res = await PermissionService.getPermissionTree()
      if (res.code === 0) {
        const treeData = res.data || []

        // 保存原始树数据
        originalPermissionTree.value = treeData

        // 构建权限映射表
        const map = new Map()
        buildPermissionMap(treeData, map)
        allPermissionsMap.value = map

        // 构建树形数据
        const fullTreeData = buildTreeData(treeData)

        // 左侧显示所有权限，但已分配的权限设置为禁用
        availablePermissions.value = setTreeNodesDisabled(
          JSON.parse(JSON.stringify(fullTreeData)),
          selectedPermissions.value
        )

        // 右侧显示已分配的权限
        if (selectedPermissions.value.length > 0) {
          assignedPermissions.value = filterTreeByIds(fullTreeData, selectedPermissions.value)
        } else {
          assignedPermissions.value = []
        }
      }
    } catch (error) {
      console.error('获取权限树失败:', error)
    }
  }

  // 获取左侧树完全勾选的节点（不包括半选节点）
  const getLeftCheckedKeys = (): number[] => {
    if (!leftTreeRef.value) return []
    return leftTreeRef.value.getCheckedKeys(false)
  }

  // 获取节点的所有父节点ID
  const getParentNodeIds = (nodeId: number): number[] => {
    const parentIds: number[] = []

    // 在原始权限树中递归查找父节点
    const findInTree = (
      treeNodes: PermissionTreeNode[],
      targetId: number,
      parentId?: number
    ): number | null => {
      for (const node of treeNodes) {
        if (node.id === targetId) {
          return parentId || null
        }
        if (node.children && node.children.length > 0) {
          const found = findInTree(node.children, targetId, node.id)
          if (found !== null) return found
        }
      }
      return null
    }

    // 递归向上查找所有父节点
    const findAllParents = (currentId: number) => {
      const parentId = findInTree(originalPermissionTree.value, currentId)
      if (parentId) {
        parentIds.push(parentId)
        findAllParents(parentId)
      }
    }

    findAllParents(nodeId)
    return parentIds
  }

  // 获取左侧树勾选的节点（包括必要的父节点，用于提交服务器）
  const getLeftCheckedKeysWithHalf = (): number[] => {
    if (!leftTreeRef.value) return []
    const checkedKeys = leftTreeRef.value.getCheckedKeys(false)
    const allIds = new Set<number>(checkedKeys)

    // 为每个勾选的节点找到所有父节点
    checkedKeys.forEach((key: number) => {
      const parents = getParentNodeIds(key)
      parents.forEach((parentId) => allIds.add(parentId))
    })

    return Array.from(allIds)
  }

  // 添加权限
  const addPermissions = async () => {
    const checkedKeys = getLeftCheckedKeys()
    if (checkedKeys.length === 0) return

    addingPermissionLoading.value = true
    try {
      // 提交到服务器时包含勾选和半选节点
      const keysToSubmit = getLeftCheckedKeysWithHalf()
      await RoleService.assignPermissions(currentRoleId.value, keysToSubmit)

      // 本地只记录完全勾选的节点
      selectedPermissions.value = [...new Set([...selectedPermissions.value, ...checkedKeys])]

      // 重新构建左右两侧树
      const fullTreeData = buildTreeData(originalPermissionTree.value)

      // 左侧显示所有权限，但已分配的权限设置为禁用
      availablePermissions.value = setTreeNodesDisabled(
        JSON.parse(JSON.stringify(fullTreeData)),
        selectedPermissions.value
      )

      // 右侧显示已分配的权限
      assignedPermissions.value = filterTreeByIds(fullTreeData, selectedPermissions.value)

      // 清空左侧树的勾选状态
      leftTreeRef.value?.setCheckedKeys([], false)
      previousCheckedKeys.value = []

      ElMessage.success('权限添加成功')
    } catch (error) {
      console.error('添加权限失败:', error)
    } finally {
      addingPermissionLoading.value = false
    }
  }

  // 移除单个权限
  const removeSinglePermission = async (data: any) => {
    try {
      // 保存右侧树的展开节点
      const expandedKeys = rightTreeRef.value?.store?.nodesMap
        ? Object.keys(rightTreeRef.value.store.nodesMap)
            .filter((key) => rightTreeRef.value.store.nodesMap[key].expanded)
            .map((key) => Number(key))
        : []

      // 获取要移除的所有权限ID（包括当前节点和所有子节点）
      const idsToRemove = [data.id, ...getAllChildrenIds(data.id)]

      // 调用API批量移除权限（传递所有需要移除的权限ID）
      await RoleService.removePermissions(currentRoleId.value, idsToRemove)

      // 更新已选权限列表（移除当前节点及其所有子节点）
      selectedPermissions.value = selectedPermissions.value.filter(
        (id) => !idsToRemove.includes(id)
      )

      // 重新构建左右两侧树
      const fullTreeData = buildTreeData(originalPermissionTree.value)

      // 左侧显示所有权限，但已分配的权限设置为禁用
      availablePermissions.value = setTreeNodesDisabled(
        JSON.parse(JSON.stringify(fullTreeData)),
        selectedPermissions.value
      )

      // 右侧显示已分配的权限
      if (selectedPermissions.value.length > 0) {
        assignedPermissions.value = filterTreeByIds(fullTreeData, selectedPermissions.value)
      } else {
        assignedPermissions.value = []
      }

      // 等待DOM更新后恢复展开状态
      await nextTick()
      if (rightTreeRef.value && expandedKeys.length > 0) {
        expandedKeys.forEach((key) => {
          const node = rightTreeRef.value.store.nodesMap[key]
          if (node && !node.isLeaf) {
            node.expanded = true
          }
        })
      }

      ElMessage.success('权限移除成功')
    } catch (error) {
      console.error('移除权限失败:', error)
    }
  }

  // 显示分配权限对话框
  const showPermissionDialog = async (row: PlatformRole) => {
    currentRoleId.value = row.ID
    currentRole.value = {
      role_name: row.role_name,
      role_type: row.role_type
    }
    selectedPermissions.value = []
    originalPermissions.value = []
    previousCheckedKeys.value = []
    leftTreeFilter.value = ''
    rightTreeFilter.value = ''

    try {
      // 加载当前角色的权限
      const res = await RoleService.getRolePermissions(row.ID)

      if (res.code === 0 || Array.isArray(res.data)) {
        // 提取权限ID数组
        const permissions = res.data || []

        if (Array.isArray(permissions) && permissions.length > 0) {
          // 如果返回的是权限对象数组，提取ID或id字段
          if (typeof permissions[0] === 'object') {
            // 优先使用ID字段，如果没有则使用id字段
            if ('ID' in permissions[0]) {
              selectedPermissions.value = permissions.map((perm: any) => perm.ID)
            } else if ('id' in permissions[0]) {
              selectedPermissions.value = permissions.map((perm: any) => perm.id)
            }
          } else {
            // 如果返回的是ID数组
            selectedPermissions.value = permissions
          }
        }

        // 保存原始权限，用于后续对比
        originalPermissions.value = [...selectedPermissions.value]
      }

      // 每次打开对话框时重新加载最新的权限列表
      await loadAllPermissions()

      // 数据加载完成后再打开对话框
      permissionDialogVisible.value = true
    } catch (error) {
      console.error('获取角色权限失败:', error)
    }
  }

  // 获取角色列表
  const getTableData = async () => {
    loading.value = true
    try {
      const params = {
        page: pagination.page,
        page_size: pagination.pageSize,
        role_name: searchForm.role_name || undefined,
        role_type: searchForm.role_type,
        status: searchForm.status
      }
      const res = await RoleService.getRoles(params)
      if (res.code === 0) {
        roleList.value = res.data.items || []
        pagination.total = res.data.total || 0
      }
    } catch (error) {
      console.error(error)
    } finally {
      loading.value = false
    }
  }

  // 重置搜索
  const handleReset = () => {
    Object.assign(searchForm, { ...initialSearchState })
    pagination.page = 1
    getTableData()
  }

  // 搜索
  const handleSearch = () => {
    pagination.page = 1
    getTableData()
  }

  // 刷新表格
  const handleRefresh = () => {
    getTableData()
  }

  // 处理表格分页变化
  const handleSizeChange = (newPageSize: number) => {
    pagination.pageSize = newPageSize
    getTableData()
  }

  const handleCurrentChange = (newCurrentPage: number) => {
    pagination.page = newCurrentPage
    getTableData()
  }

  const dialogType = ref('add')

  // 显示新增/编辑对话框
  const showDialog = async (type: string, row?: any) => {
    dialogType.value = type

    if (type === 'edit' && row) {
      let roleDetail = row
      try {
        const res = await RoleService.getRole(row.ID)
        if (res.code === 0 && res.data) {
          roleDetail = res.data
        }
      } catch (error) {
        console.error('获取角色详情失败:', error)
      }

      form.id = roleDetail.ID
      form.role_name = roleDetail.role_name
      form.role_desc = roleDetail.role_desc
      form.role_type = roleDetail.role_type
      form.status = roleDetail.status
      form.credit_enabled = Boolean(roleDetail.credit_enabled)
      form.credit_limit_yuan = fenToYuan(roleDetail.credit_limit)
    } else {
      form.id = 0
      form.role_name = ''
      form.role_desc = ''
      form.role_type = 1
      form.status = CommonStatus.ENABLED
      form.credit_enabled = false
      form.credit_limit_yuan = 0
    }

    dialogVisible.value = true
  }

  // 删除角色
  const deleteRole = (row: any) => {
    ElMessageBox.confirm(`确定删除角色 ${row.role_name} 吗？`, '删除确认', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'error'
    })
      .then(async () => {
        try {
          await RoleService.deleteRole(row.ID)
          ElMessage.success('删除成功')
          await getTableData()
        } catch (error) {
          console.error(error)
        }
      })
      .catch(() => {
        // 用户取消删除
      })
  }

  // 提交表单
  const handleSubmit = async (formEl: FormInstance | undefined) => {
    if (!formEl) return

    await formEl.validate(async (valid) => {
      if (valid) {
        submitLoading.value = true
        try {
          if (dialogType.value === 'add') {
            const data = {
              role_name: form.role_name,
              role_desc: form.role_desc,
              role_type: form.role_type,
              status: form.status
            }
            const res = await RoleService.createRole(data)
            const createdRoleId = res.data?.ID ?? res.data?.id ?? res.data?.role_id
            if (form.role_type === RoleType.CUSTOMER && createdRoleId) {
              await RoleService.updateRoleDefaultCredit(createdRoleId, getDefaultCreditPayload())
            }
            ElMessage.success('新增成功')
          } else {
            // 更新角色时只发送允许的字段
            const data = {
              role_name: form.role_name,
              role_desc: form.role_desc,
              role_type: form.role_type,
              status: form.status
            }
            await RoleService.updateRole(form.id, data)
            if (form.role_type === RoleType.CUSTOMER) {
              await RoleService.updateRoleDefaultCredit(form.id, getDefaultCreditPayload())
            }
            ElMessage.success('修改成功')
          }

          dialogVisible.value = false
          formEl.resetFields()
          await getTableData()
        } catch (error) {
          console.error(error)
        } finally {
          submitLoading.value = false
        }
      }
    })
  }

  // 状态切换
  const handleStatusChange = async (row: any, newStatus: number) => {
    const oldStatus = row.status
    // 先更新UI
    row.status = newStatus
    try {
      await RoleService.updateRoleStatus(row.ID, newStatus as 0 | 1)
      ElMessage.success('状态切换成功')
    } catch (error) {
      // 切换失败，恢复原状态
      row.status = oldStatus
      console.error(error)
    }
  }
</script>

<style scoped lang="scss">
  .dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;

    .dialog-title {
      font-size: 18px;
      font-weight: 600;
    }

    .role-info {
      display: flex;
      align-items: center;
      justify-content: space-between;

      .role-name {
        font-size: 14px;
        color: var(--el-text-color-regular);
      }
    }
  }

  .credit-form-tip {
    margin-top: 6px;
    font-size: 12px;
    line-height: 1.4;
    color: var(--el-text-color-secondary);
  }

  .permission-tree-transfer-container {
    display: flex;
    gap: 20px;
    align-items: stretch;
    justify-content: space-between;
    min-height: 500px;
    padding: 20px 0;

    .transfer-panel {
      display: flex;
      flex: 1;
      flex-direction: column;
      max-width: 440px;
      overflow: hidden;
      border: 1px solid var(--el-border-color);
      border-radius: 4px;

      .panel-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 12px 16px;
        background: var(--el-fill-color-light);
        border-bottom: 1px solid var(--el-border-color);

        .panel-title {
          font-size: 16px;
          font-weight: 600;
          color: var(--el-text-color-primary);
        }
      }

      .panel-body {
        flex: 1;
        padding: 12px;
        overflow-y: auto;

        .permission-tree {
          :deep(.el-tree-node) {
            margin: 4px 0;
          }

          :deep(.el-tree-node__content) {
            height: 36px;
            padding-right: 8px;
            line-height: 36px;
          }

          :deep(.el-tree-node__label) {
            flex: 1;
          }
        }

        .permission-tree-with-action {
          :deep(.el-tree-node__content) {
            height: auto;
            min-height: 36px;
            padding: 4px 8px 4px 0;
          }

          .tree-node-content {
            display: flex;
            gap: 8px;
            align-items: center;
            justify-content: space-between;
            width: 100%;

            .tree-node-label {
              display: flex;
              flex: 1;
              gap: 8px;
              align-items: center;
            }

            .el-button {
              flex-shrink: 0;
              margin-left: auto;
            }
          }
        }
      }
    }

    .transfer-buttons {
      display: flex;
      flex-direction: column;
      gap: 12px;
      align-items: center;
      justify-content: center;
      padding: 0 10px;

      .el-button {
        width: 100px;
      }
    }
  }
</style>
