<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')">新增角色</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%">
                <ElOption label="平台角色" :value="1" />
                <ElOption label="客户角色" :value="2" />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="状态">
              <ElSwitch
                v-model="form.status"
                :active-value="CommonStatus.ENABLED"
                :inactive-value="CommonStatus.DISABLED"
              />
            </ElFormItem>
          </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" title="分配权限" width="500px">
          <ElCheckboxGroup v-model="selectedPermissions">
            <div
              v-for="permission in allPermissions"
              :key="permission.ID"
              style="margin-bottom: 12px"
            >
              <ElCheckbox :label="permission.ID">
                {{ permission.perm_name }}
                <ElTag
                  :type="permission.perm_type === 1 ? 'info' : 'success'"
                  size="small"
                  style="margin-left: 8px"
                >
                  {{ permission.perm_type === 1 ? '菜单' : '按钮' }}
                </ElTag>
              </ElCheckbox>
            </div>
          </ElCheckboxGroup>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="permissionDialogVisible = false">取消</ElButton>
              <ElButton
                type="primary"
                @click="handleAssignPermissions"
                :loading="permissionSubmitLoading"
              >
                提交
              </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,
    ElCheckbox,
    ElCheckboxGroup,
    ElSwitch
  } from 'element-plus'
  import type { FormInstance, FormRules } from 'element-plus'
  import type { PlatformRole, Permission } from '@/types/api'
  import type { SearchFormItem } from '@/types'
  import { useCheckedColumns } from '@/composables/useCheckedColumns'
  import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
  import { formatDateTime } from '@/utils/business/format'
  import { CommonStatus, getStatusText } from '@/config/constants'

  defineOptions({ name: 'Role' })

  const dialogVisible = ref(false)
  const permissionDialogVisible = ref(false)
  const loading = ref(false)
  const submitLoading = ref(false)
  const permissionSubmitLoading = ref(false)
  const tableRef = ref()
  const currentRoleId = ref<number>(0)
  const selectedPermissions = ref<number[]>([])
  const originalPermissions = ref<number[]>([]) // 保存原始权限，用于对比
  const allPermissions = ref<Permission[]>([])

  // 搜索表单初始值
  const initialSearchState = {
    role_name: ''
  }

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

  // 搜索表单配置
  const searchFormItems: SearchFormItem[] = [
    {
      label: '角色名称',
      prop: 'role_name',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入角色名称'
      }
    }
  ]

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

  // 列配置
  const columnOptions = [
    { label: 'ID', prop: 'ID' },
    { label: '角色名称', prop: 'role_name' },
    { label: '角色描述', prop: 'role_desc' },
    { label: '角色类型', prop: 'role_type' },
    { label: '状态', prop: 'status' },
    { label: '创建时间', prop: 'CreatedAt' },
    { label: '操作', prop: 'operation' }
  ]

  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
  })

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

  // 动态列配置
  const { columnChecks, columns } = useCheckedColumns(() => [
    {
      prop: 'ID',
      label: 'ID',
      width: 80
    },
    {
      prop: 'role_name',
      label: '角色名称',
      minWidth: 120
    },
    {
      prop: 'role_desc',
      label: '角色描述',
      minWidth: 150
    },
    {
      prop: 'role_type',
      label: '角色类型',
      width: 100,
      formatter: (row: any) => {
        return h(ElTag, { type: row.role_type === 1 ? 'primary' : 'success' }, () =>
          row.role_type === 1 ? '平台角色' : '客户角色'
        )
      }
    },
    {
      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: 'CreatedAt',
      label: '创建时间',
      width: 180,
      formatter: (row: any) => formatDateTime(row.CreatedAt)
    },
    {
      prop: 'operation',
      label: '操作',
      width: 180,
      fixed: 'right',
      formatter: (row: any) => {
        return h('div', { style: 'display: flex; gap: 8px;' }, [
          h(ArtButtonTable, {
            icon: '&#xe72b;',
            onClick: () => showPermissionDialog(row)
          }),
          h(ArtButtonTable, {
            type: 'edit',
            onClick: () => showDialog('edit', row)
          }),
          h(ArtButtonTable, {
            type: 'delete',
            onClick: () => deleteRole(row)
          })
        ])
      }
    }
  ])

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

  // 加载所有权限列表
  const loadAllPermissions = async () => {
    try {
      const res = await PermissionService.getPermissions({ page: 1, page_size: 1000 })
      if (res.code === 0) {
        allPermissions.value = res.data.items || []
      }
    } catch (error) {
      console.error('获取权限列表失败:', error)
    }
  }

  // 显示分配权限对话框
  const showPermissionDialog = async (row: PlatformRole) => {
    currentRoleId.value = row.ID
    selectedPermissions.value = []
    originalPermissions.value = []

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

      // 加载当前角色的权限
      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
          if (typeof permissions[0] === 'object' && 'ID' in permissions[0]) {
            selectedPermissions.value = permissions.map((perm: any) => perm.ID)
          } else {
            // 如果返回的是ID数组
            selectedPermissions.value = permissions
          }
        }
        // 保存原始权限，用于后续对比
        originalPermissions.value = [...selectedPermissions.value]
        // 数据加载完成后再打开对话框
        permissionDialogVisible.value = true
      }
    } catch (error) {
      console.error('获取角色权限失败:', error)
    }
  }

  // 提交分配权限
  const handleAssignPermissions = async () => {
    permissionSubmitLoading.value = true
    try {
      // 对比原始权限和当前选中的权限，找出需要新增和移除的权限
      const addedPermissions = selectedPermissions.value.filter(
        (id) => !originalPermissions.value.includes(id)
      )
      const removedPermissions = originalPermissions.value.filter(
        (id) => !selectedPermissions.value.includes(id)
      )

      // 使用 Promise.all 并发执行新增和移除操作
      const promises: Promise<any>[] = []

      // 如果有新增的权限，调用分配接口
      if (addedPermissions.length > 0) {
        promises.push(RoleService.assignPermissions(currentRoleId.value, addedPermissions))
      }

      // 如果有移除的权限，调用移除接口
      if (removedPermissions.length > 0) {
        removedPermissions.forEach((permId) => {
          promises.push(RoleService.removePermission(currentRoleId.value, permId))
        })
      }

      // 等待所有操作完成
      if (promises.length > 0) {
        await Promise.all(promises)
        ElMessage.success('权限更新成功')
      } else {
        ElMessage.info('权限未发生变化')
      }

      permissionDialogVisible.value = false
    } catch (error) {
      console.error(error)
    } finally {
      permissionSubmitLoading.value = false
    }
  }

  // 获取角色列表
  const getTableData = async () => {
    loading.value = true
    try {
      const params = {
        page: pagination.page,
        pageSize: pagination.pageSize,
        role_name: searchForm.role_name || undefined
      }
      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 = (type: string, row?: any) => {
    dialogVisible.value = true
    dialogType.value = type

    if (type === 'edit' && row) {
      form.id = row.ID
      form.role_name = row.role_name
      form.role_desc = row.role_desc
      form.role_type = row.role_type
      form.status = row.status
    } else {
      form.id = 0
      form.role_name = ''
      form.role_desc = ''
      form.role_type = 1
      form.status = CommonStatus.ENABLED
    }
  }

  // 删除角色
  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 {
          const data = {
            role_name: form.role_name,
            role_desc: form.role_desc,
            role_type: form.role_type,
            status: form.status
          }

          if (dialogType.value === 'add') {
            await RoleService.createRole(data)
            ElMessage.success('新增成功')
          } else {
            await RoleService.updateRole(form.id, data)
            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>
