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

import { fetchRoles, type Role } from '@/features/admin/api/adminRoles'
import { assignAdminRoles, type AdminMgrUser } from '@/features/admin/api/adminMgr'

const props = defineProps<{
  modelValue: boolean
  admin: AdminMgrUser | null
}>()

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

const submitting = ref(false)
const loading = ref(false)
const allRoles = ref<Role[]>([])
const selectedRoleIds = ref<number[]>([])

watch(
  () => props.modelValue,
  async (val) => {
    if (val && props.admin) {
      loading.value = true
      try {
        allRoles.value = await fetchRoles()
        selectedRoleIds.value = props.admin.roles.map((r) => r.id)
      } catch {
        ElMessage.error('加载角色列表失败')
      } finally {
        loading.value = false
      }
    }
  },
)

async function handleSave() {
  if (!props.admin) return
  submitting.value = true
  try {
    await assignAdminRoles(props.admin.id, selectedRoleIds.value)
    ElMessage.success('角色已分配')
    emit('saved')
    emit('update:modelValue', false)
  } catch (error) {
    ElMessage.error(readError(error, '分配失败'))
  } finally {
    submitting.value = false
  }
}

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
}
</script>

<template>
  <el-dialog
    :model-value="modelValue"
    :title="`分配角色 - ${admin?.username || ''}`"
    width="500px"
    @update:model-value="emit('update:modelValue', $event)"
  >
    <div v-loading="loading" class="dialog-body">
      <p v-if="admin" class="admin-info">
        <strong>{{ admin.username }}</strong> · {{ admin.nickname }}
      </p>
      <el-checkbox-group v-model="selectedRoleIds">
        <div v-for="role in allRoles" :key="role.id" class="role-option">
          <el-checkbox :value="role.id" :label="role.id">
            <span class="role-name">{{ role.name }}</span>
            <span class="role-desc">{{ role.description }}</span>
          </el-checkbox>
        </div>
      </el-checkbox-group>
    </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: 16px;
}
.admin-info {
  margin: 0;
  color: #374151;
}
.role-option {
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}
.role-option:last-child {
  border-bottom: none;
}
.role-name {
  font-weight: 500;
  margin-right: 8px;
}
.role-desc {
  color: #8f9bba;
  font-size: 13px;
}
</style>
