<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ref, watch } from 'vue'

import { fetchPermissions, fetchRole, assignRolePermissions, type Permission, type Role } from '@/features/admin/api/adminRoles'

const props = defineProps<{
  modelValue: boolean
  role: Role | null
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', val: boolean): void
  (e: 'saved'): void
}>()

const submitting = ref(false)
const loading = ref(false)
const allPermissions = ref<Permission[]>([])
const selectedPermIds = ref<number[]>([])

// 按 resource 分组
const groupedPermissions = ref<Record<string, Permission[]>>({})

watch(
  () => props.modelValue,
  async (val) => {
    if (val && props.role) {
      loading.value = true
      try {
        const [perms, roleDetail] = await Promise.all([fetchPermissions(), fetchRole(props.role.id)])
        allPermissions.value = perms
        selectedPermIds.value = (roleDetail.permissions || []).map((p) => p.id)

        // 按 resource 分组
        const grouped: Record<string, Permission[]> = {}
        for (const p of perms) {
          const arr = grouped[p.resource] ?? (grouped[p.resource] = [])
          arr.push(p)
        }
        groupedPermissions.value = grouped
      } catch {
        ElMessage.error('加载权限列表失败')
      } finally {
        loading.value = false
      }
    }
  },
)

async function handleSave() {
  if (!props.role) return
  submitting.value = true
  try {
    await assignRolePermissions(props.role.id, selectedPermIds.value)
    ElMessage.success('权限已分配')
    emit('saved')
    emit('update:modelValue', false)
  } catch (error) {
    ElMessage.error(readError(error, '分配失败'))
  } finally {
    submitting.value = false
  }
}

function toggleGroup(perms: Permission[]) {
  const ids = perms.map((p) => p.id)
  const allSelected = ids.every((id) => selectedPermIds.value.includes(id))
  if (allSelected) {
    selectedPermIds.value = selectedPermIds.value.filter((id) => !ids.includes(id))
  } else {
    const newIds = [...selectedPermIds.value]
    for (const id of ids) {
      if (!newIds.includes(id)) newIds.push(id)
    }
    selectedPermIds.value = newIds
  }
}

function isGroupAllSelected(perms: Permission[]) {
  return perms.length > 0 && perms.every((p) => selectedPermIds.value.includes(p.id))
}

function isGroupPartial(perms: Permission[]) {
  return perms.some((p) => selectedPermIds.value.includes(p.id)) && !isGroupAllSelected(perms)
}

function readError(error: unknown, fallback: string) {
  if (typeof error === 'object' && error && 'response' in error) {
    const response = (error as { response?: { data?: { message?: string } } }).response
    return response?.data?.message || fallback
  }
  return fallback
}

const resourceLabels: Record<string, string> = {
  dashboard: '仪表盘',
  user: '用户管理',
  order: '订单管理',
  listing: '商品管理',
  dispute: '仲裁中心',
  chat: '客服群聊',
  wallet: '资金流水',
  admin_user: '管理员管理',
  role: '角色管理',
  system_config: '系统配置',
  audit_log: '审计日志',
}
</script>

<template>
  <el-dialog
    :model-value="modelValue"
    :title="`分配权限 - ${role?.name || ''}`"
    width="600px"
    @update:model-value="emit('update:modelValue', $event)"
  >
    <div v-loading="loading" class="dialog-body">
      <p v-if="role" class="role-info">
        <strong>{{ role.name }}</strong> · {{ role.description }}
      </p>
      <div v-for="(perms, resource) in groupedPermissions" :key="resource" class="perm-group">
        <div class="perm-group-header">
          <el-checkbox
            :model-value="isGroupAllSelected(perms)"
            :indeterminate="isGroupPartial(perms)"
            @change="toggleGroup(perms)"
          >
            <strong>{{ resourceLabels[resource] || resource }}</strong>
          </el-checkbox>
        </div>
        <div class="perm-group-items">
          <el-checkbox
            v-for="perm in perms"
            :key="perm.id"
            v-model="selectedPermIds"
            :value="perm.id"
            :label="perm.id"
          >
            {{ perm.name }}
          </el-checkbox>
        </div>
      </div>
    </div>
    <template #footer>
      <el-button @click="emit('update:modelValue', false)">取消</el-button>
      <el-button type="primary" :loading="submitting" @click="handleSave">保存</el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.dialog-body {
  display: grid;
  gap: 12px;
  max-height: 60vh;
  overflow-y: auto;
}
.role-info {
  margin: 0;
  color: #374151;
}
.perm-group {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 12px 16px;
}
.perm-group-header {
  margin-bottom: 8px;
}
.perm-group-items {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding-left: 24px;
}
</style>
