<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import {
  getEmployeesByPage,
  getDeletedEmployees,
  getAllRoles,
  createEmployee,
  updateEmployee,
  deleteEmployee,
  changeEmployeePassword,
  assignRoles,
  type EmployeeInfo,
  type EmployeePageResponse,
  type SysRole,
  type RoleInfo,
  type CreateEmployeeDto,
} from '@/api/employee'
import { verifyAdminPassword } from '@/api/member'
import AppLayout from '@/components/AppLayout.vue'
import { useToast } from '@/composables/useToast'

const toast = useToast()

// ==================== 列表数据 ====================
const employees = ref<EmployeeInfo[]>([])
const deletedEmployees = ref<EmployeeInfo[]>([])
const showDeleted = ref(false)
const loadingDeleted = ref(false)
const roles = ref<SysRole[]>([])
const loading = ref(false)
const keyword = ref('')

const currentPage = ref(0)
const pageSize = ref(10)
const totalElements = ref(0)
const totalPages = ref(0)

// ==================== 创建账号弹窗 ====================
const showCreateModal = ref(false)
const createLoading = ref(false)
const createForm = ref<CreateEmployeeDto & { confirmPassword: string }>({
  username: '',
  password: '',
  confirmPassword: '',
  nickname: '',
  email: '',
  phone: '',
  roles: [],
})
const createErrors = ref<Record<string, string>>({})

// ==================== 编辑账号弹窗 ====================
const showEditModal = ref(false)
const editLoading = ref(false)
const editEmployee = ref<EmployeeInfo | null>(null)
const editStatus = ref(1)

// ==================== 分配角色弹窗 ====================
const showRoleModal = ref(false)
const roleLoading = ref(false)
const roleEmployee = ref<EmployeeInfo | null>(null)
const selectedRoleIds = ref<number[]>([])

// ==================== 修改密码弹窗 ====================
const showPasswordModal = ref(false)
const passwordLoading = ref(false)
const passwordEmployee = ref<EmployeeInfo | null>(null)
const newPassword = ref('')
const confirmNewPassword = ref('')

// ==================== 删除确认弹窗 ====================
const showDeleteModal = ref(false)
const deleteEmployeeTarget = ref<EmployeeInfo | null>(null)
const deleteLoading = ref(false)

// ==================== 计算属性 ====================
const statusMap: Record<number, string> = { 0: '禁用', 1: '正常' }

// ==================== 超级管理员密码验证 ====================
const showAdminPwdModal = ref(false)
const adminPwdInput = ref('')
const adminPwdError = ref('')
const adminPwdLoading = ref(false)
let adminPwdResolve: ((ok: boolean) => void) | null = null

function isAdmin(emp: EmployeeInfo): boolean {
  return emp.id === 1
}

function isDeleted(emp: EmployeeInfo): boolean {
  return emp.deletedAt !== null
}

function requireAdminPassword(): Promise<boolean> {
  return new Promise((resolve) => {
    adminPwdInput.value = ''
    adminPwdError.value = ''
    adminPwdResolve = resolve
    showAdminPwdModal.value = true
  })
}

async function confirmAdminPassword() {
  if (!adminPwdInput.value) {
    adminPwdError.value = '请输入超级管理员密码'
    return
  }
  adminPwdLoading.value = true
  adminPwdError.value = ''
  try {
    const ok = await verifyAdminPassword(adminPwdInput.value)
    if (ok) {
      showAdminPwdModal.value = false
      adminPwdResolve?.(true)
    } else {
      adminPwdError.value = '密码错误'
    }
  } catch {
    adminPwdError.value = '验证失败'
  } finally {
    adminPwdLoading.value = false
  }
}

function cancelAdminPassword() {
  showAdminPwdModal.value = false
  adminPwdResolve?.(false)
}

// ==================== 数据获取 ====================
async function fetchEmployees() {
  loading.value = true
  try {
    const res: EmployeePageResponse = await getEmployeesByPage({
      page: currentPage.value,
      size: pageSize.value,
      sort: 'id',
      order: 'asc',
      keyword: keyword.value || undefined,
    })
    employees.value = res.content
    totalElements.value = res.totalElements
    totalPages.value = res.totalPages
  } catch (e: any) {
    employees.value = []
    const msg = e?.response?.data?.error || e?.response?.data?.message || e?.message || '获取账号列表失败'
    toast.error(msg)
  } finally {
    loading.value = false
  }
}

async function fetchRoles() {
  try {
    roles.value = await getAllRoles()
  } catch {
    // ignore
  }
}

async function fetchDeletedEmployees() {
  if (deletedEmployees.value.length > 0) return // 已加载过则不重复请求
  loadingDeleted.value = true
  try {
    const res = await getDeletedEmployees({ page: 0, size: 100 })
    deletedEmployees.value = res.content.filter((e) => e.deletedAt !== null)
  } catch {
    // ignore
  } finally {
    loadingDeleted.value = false
  }
}

function toggleDeleted() {
  showDeleted.value = !showDeleted.value
  if (showDeleted.value) {
    fetchDeletedEmployees()
  }
}

function handleSearch() {
  currentPage.value = 0
  fetchEmployees()
}

function handleReset() {
  keyword.value = ''
  currentPage.value = 0
  fetchEmployees()
}

function goPage(page: number) {
  if (page < 0 || page >= totalPages.value) return
  currentPage.value = page
  fetchEmployees()
}

// ==================== 创建账号 ====================
function openCreateModal() {
  createForm.value = {
    username: '',
    password: '',
    confirmPassword: '',
    nickname: '',
    email: '',
    phone: '',
    roles: [],
  }
  createErrors.value = {}
  showCreateModal.value = true
}

function validateCreateForm(): boolean {
  const errs: Record<string, string> = {}
  if (!createForm.value.username || createForm.value.username.length < 3) {
    errs.username = '用户名至少3位'
  }
  if (!/^[a-zA-Z0-9_-]+$/.test(createForm.value.username)) {
    errs.username = '用户名只能包含字母、数字、下划线和横线'
  }
  if (!createForm.value.password) {
    errs.password = '密码不能为空'
  } else if (createForm.value.password.length < 8) {
    errs.password = '密码至少8位'
  } else if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/.test(createForm.value.password)) {
    errs.password = '密码必须包含大小写字母和数字'
  }
  if (createForm.value.password !== createForm.value.confirmPassword) {
    errs.confirmPassword = '两次密码不一致'
  }
  if (!createForm.value.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(createForm.value.email)) {
    errs.email = '请输入正确的邮箱'
  }
  if (!createForm.value.phone || !/^1[3-9]\d{9}$/.test(createForm.value.phone)) {
    errs.phone = '请输入正确的手机号'
  }
  createErrors.value = errs
  return Object.keys(errs).length === 0
}

function toggleRoleSelection(roleId: number) {
  const idx = createForm.value.roles!.indexOf(roleId)
  if (idx >= 0) {
    createForm.value.roles!.splice(idx, 1)
  } else {
    createForm.value.roles!.push(roleId)
  }
}

async function handleCreate() {
  if (!validateCreateForm()) return
  createLoading.value = true
  try {
    const payload: CreateEmployeeDto = {
      username: createForm.value.username,
      password: createForm.value.password,
      nickname: createForm.value.nickname || undefined,
      email: createForm.value.email,
      phone: createForm.value.phone,
      roles: createForm.value.roles!.length > 0 ? createForm.value.roles : undefined,
    }
    await createEmployee(payload)
    toast.success('账号创建成功')
    showCreateModal.value = false
    fetchEmployees()
  } catch (e: any) {
    const msg = e?.response?.data?.error || e?.response?.data?.message || e?.message || '创建失败'
    toast.error(msg)
  } finally {
    createLoading.value = false
  }
}

// ==================== 编辑账号 ====================
function openEditModal(emp: EmployeeInfo) {
  editEmployee.value = emp
  editStatus.value = emp.status
  showEditModal.value = true
}

async function handleEdit() {
  if (!editEmployee.value) return
  showEditModal.value = false
  const ok = await requireAdminPassword()
  if (!ok) { showEditModal.value = true; return }
  editLoading.value = true
  try {
    await updateEmployee(editEmployee.value.id, {
      email: editEmployee.value.email,
      status: editStatus.value,
    })
    toast.success('账号信息更新成功')
    fetchEmployees()
  } catch (e: any) {
    const msg = e?.response?.data?.error || e?.response?.data?.message || e?.message || '更新失败'
    toast.error(msg)
  } finally {
    editLoading.value = false
  }
}

// ==================== 分配角色 ====================
function openRoleModal(emp: EmployeeInfo) {
  roleEmployee.value = emp
  selectedRoleIds.value = emp.roles.map((r) => r.id)
  showRoleModal.value = true
}

function toggleSelectedRole(roleId: number) {
  const idx = selectedRoleIds.value.indexOf(roleId)
  if (idx >= 0) {
    selectedRoleIds.value.splice(idx, 1)
  } else {
    selectedRoleIds.value.push(roleId)
  }
}

async function handleAssignRoles() {
  if (!roleEmployee.value) return
  showRoleModal.value = false
  const ok = await requireAdminPassword()
  if (!ok) { showRoleModal.value = true; return }
  roleLoading.value = true
  try {
    await assignRoles(roleEmployee.value.id, {
      roleIds: selectedRoleIds.value.map(String),
    })
    toast.success('角色分配成功')
    fetchEmployees()
  } catch (e: any) {
    const msg = e?.response?.data?.error || e?.response?.data?.message || e?.message || '角色分配失败'
    toast.error(msg)
  } finally {
    roleLoading.value = false
  }
}

// ==================== 修改密码 ====================
function openPasswordModal(emp: EmployeeInfo) {
  passwordEmployee.value = emp
  newPassword.value = ''
  confirmNewPassword.value = ''
  showPasswordModal.value = true
}

async function handleChangePassword() {
  if (!passwordEmployee.value) return
  showPasswordModal.value = false
  const ok = await requireAdminPassword()
  if (!ok) return
  if (newPassword.value.length < 8) {
    toast.error('新密码至少8位')
    return
  }
  if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/.test(newPassword.value)) {
    toast.error('密码必须包含大小写字母和数字')
    return
  }
  if (newPassword.value !== confirmNewPassword.value) {
    toast.error('两次密码不一致')
    return
  }
  passwordLoading.value = true
  try {
    await changeEmployeePassword(passwordEmployee.value.id, {
      oldPassword: 'admin-reset',
      newPassword: newPassword.value,
    })
    toast.success('密码重置成功')
    showPasswordModal.value = false
  } catch (e: any) {
    const msg = e?.response?.data?.message || e?.message || '密码重置失败'
    toast.error(msg)
  } finally {
    passwordLoading.value = false
  }
}

// ==================== 删除账号 ====================
function openDeleteModal(emp: EmployeeInfo) {
  deleteEmployeeTarget.value = emp
  showDeleteModal.value = true
}

async function handleDelete() {
  if (!deleteEmployeeTarget.value) return
  showDeleteModal.value = false
  const ok = await requireAdminPassword()
  if (!ok) return
  deleteLoading.value = true
  try {
    const target = deleteEmployeeTarget.value
    await deleteEmployee(target.id)
    toast.success('账号已删除（逻辑删除）')
    fetchEmployees()
    deletedEmployees.value = [] // 清空缓存，下次展开时重新加载
  } catch (e: any) {
    const msg = e?.response?.data?.error || e?.response?.data?.message || e?.message || '删除失败'
    toast.error(msg)
  } finally {
    deleteLoading.value = false
  }
}

// ==================== 工具函数 ====================
function formatTime(t: string | null): string {
  if (!t) return '--'
  return new Date(t).toLocaleString('zh-CN')
}

function getRoleNames(roles: RoleInfo[] | undefined): string {
  if (!roles || roles.length === 0) return '未分配'
  return roles.map((r) => r.roleName).join('、')
}

// ==================== 初始化 ====================
onMounted(() => {
  fetchEmployees()
  fetchRoles()
})
</script>

<template>
  <AppLayout>
    <!-- ========== 筛选栏 ========== -->
    <div class="filter-bar">
      <div class="filter-row">
        <input
          v-model="keyword"
          class="filter-input"
          placeholder="搜索用户名/昵称..."
          @keyup.enter="handleSearch"
        />
        <button class="btn btn-primary" @click="handleSearch">
          <i class="fas fa-search"></i> 查询
        </button>
        <button class="btn btn-outline" @click="handleReset">
          <i class="fas fa-redo"></i> 重置
        </button>
        <div class="filter-spacer"></div>
        <button class="btn btn-primary" @click="openCreateModal">
          <i class="fas fa-plus"></i> 新增账号
        </button>
      </div>
    </div>

    <!-- ========== 数据表格 ========== -->
    <div class="table-container">
      <table class="data-table" v-if="!loading">
        <thead>
          <tr>
            <th style="width: 60px">ID</th>
            <th style="width: 120px">用户名</th>
            <th style="width: 100px">昵称</th>
            <th style="width: 180px">邮箱</th>
            <th style="width: 130px">手机号</th>
            <th style="width: 160px">角色</th>
            <th style="width: 70px">状态</th>
            <th style="width: 150px">创建时间</th>
            <th style="width: 200px">操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-if="employees.length === 0">
            <td colspan="9" class="empty-cell">暂无账号数据</td>
          </tr>
          <tr v-for="emp in employees" :key="emp.id">
            <td>{{ emp.id }}</td>
            <td class="text-mono">{{ emp.username }}</td>
            <td>{{ emp.nickname || '--' }}</td>
            <td>{{ emp.email }}</td>
            <td>{{ emp.phone }}</td>
            <td>
              <span class="role-tags">{{ getRoleNames(emp.roles) }}</span>
            </td>
            <td>
              <span class="status-badge" :class="emp.status === 1 ? 'active' : 'inactive'">
                {{ statusMap[emp.status] }}
              </span>
            </td>
            <td>{{ formatTime(emp.createdAt) }}</td>
            <td class="action-cell">
              <button class="btn btn-sm btn-outline" :disabled="isAdmin(emp) || isDeleted(emp)" @click="!isAdmin(emp) && !isDeleted(emp) && openEditModal(emp)">
                <i class="fas fa-edit"></i> 编辑
              </button>
              <button class="btn btn-sm btn-outline" :disabled="isAdmin(emp) || isDeleted(emp)" @click="!isAdmin(emp) && !isDeleted(emp) && openRoleModal(emp)">
                <i class="fas fa-user-tag"></i> 角色
              </button>
              <button class="btn btn-sm btn-outline" :disabled="isAdmin(emp) || isDeleted(emp)" @click="!isAdmin(emp) && !isDeleted(emp) && openPasswordModal(emp)">
                <i class="fas fa-key"></i> 密码
              </button>
              <button class="btn btn-sm btn-danger" :disabled="isAdmin(emp) || isDeleted(emp)" @click="!isAdmin(emp) && !isDeleted(emp) && openDeleteModal(emp)">
                <i class="fas fa-trash"></i>
              </button>
            </td>
          </tr>
        </tbody>
      </table>

      <!-- 加载骨架 -->
      <div v-else class="loading-state">
        <i class="fas fa-spinner fa-spin"></i> 加载中...
      </div>
    </div>

    <!-- ========== 分页 ========== -->
    <div class="pagination-bar" v-if="totalPages > 1">
      <span class="page-info">共 {{ totalElements }} 条，第 {{ currentPage + 1 }}/{{ totalPages }} 页</span>
      <div class="page-btns">
        <button class="btn btn-sm btn-outline" :disabled="currentPage <= 0" @click="goPage(0)">
          <i class="fas fa-angle-double-left"></i>
        </button>
        <button class="btn btn-sm btn-outline" :disabled="currentPage <= 0" @click="goPage(currentPage - 1)">
          <i class="fas fa-angle-left"></i>
        </button>
        <button class="btn btn-sm btn-outline" :disabled="currentPage >= totalPages - 1" @click="goPage(currentPage + 1)">
          <i class="fas fa-angle-right"></i>
        </button>
        <button class="btn btn-sm btn-outline" :disabled="currentPage >= totalPages - 1" @click="goPage(totalPages - 1)">
          <i class="fas fa-angle-double-right"></i>
        </button>
      </div>
    </div>

    <!-- ========== 已删除账号（折叠） ========== -->
    <div class="deleted-section">
      <div class="deleted-toggle" @click="toggleDeleted">
        <i :class="showDeleted ? 'fas fa-chevron-down' : 'fas fa-chevron-right'"></i>
        <i class="fas fa-trash-alt"></i>
        <span>已删除账号</span>
        <span class="deleted-count" v-if="deletedEmployees.length > 0">({{ deletedEmployees.length }})</span>
      </div>
      <div class="deleted-content" v-if="showDeleted">
        <div class="deleted-loading" v-if="loadingDeleted">
          <i class="fas fa-spinner fa-spin"></i> 加载中...
        </div>
        <table class="data-table deleted-table" v-else-if="deletedEmployees.length > 0">
          <thead>
            <tr>
              <th style="width: 60px">ID</th>
              <th style="width: 120px">用户名</th>
              <th style="width: 100px">昵称</th>
              <th style="width: 180px">邮箱</th>
              <th style="width: 130px">手机号</th>
              <th style="width: 160px">角色</th>
              <th style="width: 70px">状态</th>
              <th style="width: 150px">删除时间</th>
              <th style="width: 200px">操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="emp in deletedEmployees" :key="emp.id" class="deleted-row">
              <td>{{ emp.id }}</td>
              <td class="text-mono">{{ emp.username }}</td>
              <td>{{ emp.nickname || '--' }}</td>
              <td>{{ emp.email }}</td>
              <td>{{ emp.phone }}</td>
              <td>
                <span class="role-tags">{{ getRoleNames(emp.roles) }}</span>
              </td>
              <td>
                <span class="status-badge deleted-badge">已删除</span>
              </td>
              <td>{{ formatTime(emp.deletedAt) }}</td>
              <td class="action-cell">
                <span class="no-action">不可操作</span>
              </td>
            </tr>
          </tbody>
        </table>
        <div class="deleted-empty" v-else-if="!loadingDeleted">
          <i class="fas fa-inbox"></i> 暂无已删除账号
        </div>
      </div>
    </div>

    <!-- ========== 创建账号弹窗 ========== -->
    <Teleport to="body">
      <div class="modal-overlay" v-if="showCreateModal" @click.self="showCreateModal = false">
        <div class="modal-box">
          <div class="modal-header">
            <h3><i class="fas fa-user-plus"></i> 新增账号</h3>
            <button class="modal-close" @click="showCreateModal = false">&times;</button>
          </div>
          <div class="modal-body">
            <div class="form-group">
              <label>用户名 <span class="required">*</span></label>
              <input v-model="createForm.username" class="form-input" placeholder="3-50位字母数字" />
              <span class="field-error" v-if="createErrors.username">{{ createErrors.username }}</span>
            </div>
            <div class="form-row">
              <div class="form-group">
                <label>密码 <span class="required">*</span></label>
                <input v-model="createForm.password" type="password" class="form-input" placeholder="8-20位含大小写字母数字" />
                <span class="field-error" v-if="createErrors.password">{{ createErrors.password }}</span>
              </div>
              <div class="form-group">
                <label>确认密码 <span class="required">*</span></label>
                <input v-model="createForm.confirmPassword" type="password" class="form-input" placeholder="再次输入密码" />
                <span class="field-error" v-if="createErrors.confirmPassword">{{ createErrors.confirmPassword }}</span>
              </div>
            </div>
            <div class="form-group">
              <label>昵称</label>
              <input v-model="createForm.nickname" class="form-input" placeholder="显示名称" />
            </div>
            <div class="form-group">
              <label>邮箱 <span class="required">*</span></label>
              <input v-model="createForm.email" class="form-input" placeholder="staff@novalon.com" />
              <span class="field-error" v-if="createErrors.email">{{ createErrors.email }}</span>
            </div>
            <div class="form-group">
              <label>手机号 <span class="required">*</span></label>
              <input v-model="createForm.phone" class="form-input" placeholder="13800138000" />
              <span class="field-error" v-if="createErrors.phone">{{ createErrors.phone }}</span>
            </div>
            <div class="form-group">
              <label>分配角色</label>
              <div class="role-checkbox-group">
                <label
                  v-for="role in roles"
                  :key="role.id"
                  class="role-checkbox"
                  :class="{ checked: createForm.roles!.includes(role.id) }"
                  @click="toggleRoleSelection(role.id)"
                >
                  <i :class="createForm.roles!.includes(role.id) ? 'fas fa-check-square' : 'far fa-square'"></i>
                  {{ role.roleName }}
                  <span class="role-key-tag">{{ role.roleKey }}</span>
                </label>
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-outline" @click="showCreateModal = false">取消</button>
            <button class="btn btn-primary" :disabled="createLoading" @click="handleCreate">
              <i class="fas fa-spinner fa-spin" v-if="createLoading"></i>
              {{ createLoading ? '创建中...' : '创建账号' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- ========== 编辑账号弹窗 ========== -->
    <Teleport to="body">
      <div class="modal-overlay" v-if="showEditModal" @click.self="showEditModal = false">
        <div class="modal-box modal-sm">
          <div class="modal-header">
            <h3><i class="fas fa-edit"></i> 编辑账号</h3>
            <button class="modal-close" @click="showEditModal = false">&times;</button>
          </div>
          <div class="modal-body" v-if="editEmployee">
            <div class="form-group">
              <label>用户名</label>
              <input :value="editEmployee.username" class="form-input" disabled />
            </div>
            <div class="form-group">
              <label>邮箱</label>
              <input v-model="editEmployee.email" class="form-input" />
            </div>
            <div class="form-group">
              <label>手机号</label>
              <input :value="editEmployee.phone" class="form-input" disabled />
            </div>
            <div class="form-group">
              <label>状态</label>
              <select v-model="editStatus" class="form-input">
                <option :value="1">正常</option>
                <option :value="0">禁用</option>
              </select>
            </div>
            <div class="form-group">
              <label>当前角色</label>
              <div class="role-readonly">{{ getRoleNames(editEmployee.roles) }}</div>
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-outline" @click="showEditModal = false">取消</button>
            <button class="btn btn-primary" :disabled="editLoading" @click="handleEdit">
              <i class="fas fa-spinner fa-spin" v-if="editLoading"></i>
              {{ editLoading ? '保存中...' : '保存' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- ========== 分配角色弹窗 ========== -->
    <Teleport to="body">
      <div class="modal-overlay" v-if="showRoleModal" @click.self="showRoleModal = false">
        <div class="modal-box modal-sm">
          <div class="modal-header">
            <h3><i class="fas fa-user-tag"></i> 分配角色</h3>
            <button class="modal-close" @click="showRoleModal = false">&times;</button>
          </div>
          <div class="modal-body" v-if="roleEmployee">
            <p class="modal-desc">为账号 <strong>{{ roleEmployee.username }}</strong> 分配角色：</p>
            <div class="role-checkbox-group">
              <label
                v-for="role in roles"
                :key="role.id"
                class="role-checkbox"
                :class="{ checked: selectedRoleIds.includes(role.id) }"
                @click="toggleSelectedRole(role.id)"
              >
                <i :class="selectedRoleIds.includes(role.id) ? 'fas fa-check-square' : 'far fa-square'"></i>
                {{ role.roleName }}
                <span class="role-key-tag">{{ role.roleKey }}</span>
              </label>
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-outline" @click="showRoleModal = false">取消</button>
            <button class="btn btn-primary" :disabled="roleLoading" @click="handleAssignRoles">
              <i class="fas fa-spinner fa-spin" v-if="roleLoading"></i>
              {{ roleLoading ? '保存中...' : '保存' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- ========== 修改密码弹窗 ========== -->
    <Teleport to="body">
      <div class="modal-overlay" v-if="showPasswordModal" @click.self="showPasswordModal = false">
        <div class="modal-box modal-sm">
          <div class="modal-header">
            <h3><i class="fas fa-key"></i> 重置密码</h3>
            <button class="modal-close" @click="showPasswordModal = false">&times;</button>
          </div>
          <div class="modal-body" v-if="passwordEmployee">
            <p class="modal-desc">为账号 <strong>{{ passwordEmployee.username }}</strong> 设置新密码：</p>
            <div class="form-group">
              <label>新密码</label>
              <input v-model="newPassword" type="password" class="form-input" placeholder="8-20位含大小写字母数字" />
            </div>
            <div class="form-group">
              <label>确认新密码</label>
              <input v-model="confirmNewPassword" type="password" class="form-input" placeholder="再次输入新密码" />
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-outline" @click="showPasswordModal = false">取消</button>
            <button class="btn btn-primary" :disabled="passwordLoading" @click="handleChangePassword">
              <i class="fas fa-spinner fa-spin" v-if="passwordLoading"></i>
              {{ passwordLoading ? '重置中...' : '确认重置' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- ========== 删除确认弹窗 ========== -->
    <Teleport to="body">
      <div class="modal-overlay" v-if="showDeleteModal" @click.self="showDeleteModal = false">
        <div class="modal-box modal-sm">
          <div class="modal-header">
            <h3><i class="fas fa-exclamation-triangle" style="color: #e74c3c"></i> 确认删除</h3>
            <button class="modal-close" @click="showDeleteModal = false">&times;</button>
          </div>
          <div class="modal-body">
            <p class="modal-desc">
              确定要删除账号 <strong>{{ deleteEmployeeTarget?.username }}</strong> 吗？<br />
              <em style="color: #8b9ab0">（逻辑删除，可恢复）</em>
            </p>
          </div>
          <div class="modal-footer">
            <button class="btn btn-outline" @click="showDeleteModal = false">取消</button>
            <button class="btn btn-danger" :disabled="deleteLoading" @click="handleDelete">
              <i class="fas fa-spinner fa-spin" v-if="deleteLoading"></i>
              {{ deleteLoading ? '删除中...' : '确认删除' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>

    <!-- ========== 管理员密码验证弹窗 ========== -->
    <Teleport to="body">
      <div class="modal-overlay" v-if="showAdminPwdModal" @click.self="cancelAdminPassword">
        <div class="modal-box modal-sm">
          <div class="modal-header">
            <h3><i class="fas fa-lock"></i> 管理员验证</h3>
            <button class="modal-close" @click="cancelAdminPassword">&times;</button>
          </div>
          <div class="modal-body">
            <p class="modal-desc">此操作需要超级管理员密码验证：</p>
            <div class="form-group">
              <label>管理员密码</label>
              <input v-model="adminPwdInput" type="password" class="form-input" placeholder="请输入超级管理员密码" @keyup.enter="confirmAdminPassword" />
              <span class="field-error" v-if="adminPwdError">{{ adminPwdError }}</span>
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-outline" @click="cancelAdminPassword">取消</button>
            <button class="btn btn-primary" :disabled="adminPwdLoading" @click="confirmAdminPassword">
              <i class="fas fa-spinner fa-spin" v-if="adminPwdLoading"></i>
              {{ adminPwdLoading ? '验证中...' : '确认' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>
  </AppLayout>
</template>

<style scoped>
/* ==================== 筛选栏 ==================== */
.filter-bar {
  margin-bottom: 20px;
}

.filter-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.filter-input {
  padding: 8px 14px;
  border: 1px solid #dde2eb;
  border-radius: 8px;
  font-size: 14px;
  outline: none;
  width: 220px;
  transition: border-color 0.2s;
}

.filter-input:focus {
  border-color: #4f7cff;
}

.filter-spacer {
  flex: 1;
}

/* ==================== 表格 ==================== */
.table-container {
  background: #ffffff;
  border-radius: 12px;
  border: 1px solid #e9edf4;
  overflow: hidden;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.data-table th {
  background: #f8f9fc;
  color: #5a6a85;
  font-weight: 600;
  text-align: left;
  padding: 12px 16px;
  border-bottom: 1px solid #e9edf4;
  white-space: nowrap;
}

.data-table td {
  padding: 12px 16px;
  border-bottom: 1px solid #f0f3f8;
  color: #1e293b;
}

.data-table tbody tr:hover {
  background: #f8f9fc;
}

.empty-cell {
  text-align: center;
  color: #8b9ab0;
  padding: 40px 16px !important;
}

.text-mono {
  font-family: 'Consolas', 'Monaco', monospace;
  font-weight: 500;
}

.action-cell {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.role-tags {
  color: #4f7cff;
  font-weight: 500;
}

.status-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
}

.status-badge.active {
  background: #e8f5e9;
  color: #2e7d32;
}

.status-badge.inactive {
  background: #fce4e4;
  color: #c62828;
}

.loading-state {
  padding: 60px;
  text-align: center;
  color: #8b9ab0;
  font-size: 15px;
}

/* ==================== 按钮 ==================== */
.btn {
  padding: 8px 16px;
  border-radius: 8px;
  border: none;
  font-size: 14px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  transition: all 0.2s;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn-primary {
  background: #4f7cff;
  color: #ffffff;
}

.btn-primary:hover:not(:disabled) {
  background: #3b5fd9;
}

.btn-outline {
  background: #ffffff;
  color: #4a5568;
  border: 1px solid #dde2eb;
}

.btn-outline:hover:not(:disabled) {
  background: #f0f3f8;
}

.btn-danger {
  background: #e74c3c;
  color: #ffffff;
}

.btn-danger:hover:not(:disabled) {
  background: #c0392b;
}

.btn-sm {
  padding: 5px 10px;
  font-size: 12px;
  border-radius: 6px;
}

/* ==================== 分页 ==================== */
.pagination-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
  padding: 12px 16px;
  background: #ffffff;
  border-radius: 10px;
  border: 1px solid #e9edf4;
}

.page-info {
  color: #5a6a85;
  font-size: 14px;
}

.page-btns {
  display: flex;
  gap: 6px;
}

/* ==================== 弹窗 ==================== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.2s ease;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.modal-box {
  background: #ffffff;
  border-radius: 14px;
  width: 560px;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}

.modal-sm {
  width: 440px;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px 16px;
  border-bottom: 1px solid #e9edf4;
}

.modal-header h3 {
  font-size: 17px;
  font-weight: 600;
  color: #0b1a33;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.modal-close {
  background: none;
  border: none;
  font-size: 24px;
  color: #8b9ab0;
  cursor: pointer;
  padding: 0;
  line-height: 1;
}

.modal-close:hover {
  color: #e74c3c;
}

.modal-body {
  padding: 20px 24px;
}

.modal-desc {
  margin: 0 0 16px;
  color: #4a5568;
  font-size: 14px;
  line-height: 1.6;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px 24px;
  border-top: 1px solid #e9edf4;
}

/* ==================== 表单 ==================== */
.form-group {
  margin-bottom: 16px;
}

.form-group label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: #374151;
  margin-bottom: 6px;
}

.required {
  color: #e74c3c;
}

.form-input {
  width: 100%;
  padding: 9px 14px;
  border: 1px solid #dde2eb;
  border-radius: 8px;
  font-size: 14px;
  outline: none;
  transition: border-color 0.2s;
  box-sizing: border-box;
}

.form-input:focus {
  border-color: #4f7cff;
  box-shadow: 0 0 0 3px rgba(79, 124, 255, 0.1);
}

.form-input:disabled {
  background: #f0f3f8;
  color: #8b9ab0;
}

.field-error {
  display: block;
  color: #e74c3c;
  font-size: 12px;
  margin-top: 4px;
}

.form-row {
  display: flex;
  gap: 14px;
}

.form-row .form-group {
  flex: 1;
}

/* ==================== 角色选择 ==================== */
.role-checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.role-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid #dde2eb;
  border-radius: 8px;
  font-size: 13px;
  color: #4a5568;
  cursor: pointer;
  transition: all 0.2s;
  user-select: none;
}

.role-checkbox:hover {
  border-color: #4f7cff;
}

.role-checkbox.checked {
  background: #eef2ff;
  border-color: #4f7cff;
  color: #4f7cff;
  font-weight: 500;
}

.role-key-tag {
  font-size: 11px;
  color: #8b9ab0;
  background: #f0f3f8;
  padding: 1px 6px;
  border-radius: 4px;
}

.role-readonly {
  padding: 9px 14px;
  background: #f8f9fc;
  border-radius: 8px;
  color: #4f7cff;
  font-weight: 500;
  font-size: 14px;
}

.btn:disabled,
.btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* ==================== 已删除账号区域 ==================== */
.deleted-section {
  margin-top: 20px;
  border: 1px solid #e0e4ed;
  border-radius: 10px;
  overflow: hidden;
  background: #fafbfc;
}

.deleted-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  cursor: pointer;
  user-select: none;
  font-size: 14px;
  color: #8b9ab0;
  transition: color 0.2s;
}

.deleted-toggle:hover {
  color: #4f7cff;
  background: #f0f3f8;
}

.deleted-toggle i:first-child {
  font-size: 12px;
  width: 14px;
  transition: transform 0.2s;
}

.deleted-count {
  color: #e74c3c;
  font-weight: 500;
}

.deleted-content {
  border-top: 1px solid #e9edf4;
}

.deleted-loading {
  padding: 24px;
  text-align: center;
  color: #8b9ab0;
  font-size: 14px;
}

.deleted-empty {
  padding: 32px;
  text-align: center;
  color: #8b9ab0;
  font-size: 14px;
}

.deleted-empty i {
  display: block;
  font-size: 32px;
  margin-bottom: 8px;
  opacity: 0.4;
}

.deleted-table {
  margin: 0;
  border-radius: 0;
  box-shadow: none;
}

.deleted-table th {
  background: #f0f3f8;
  color: #8b9ab0;
}

.deleted-row {
  opacity: 0.6;
  background: #fafbfc;
}

.deleted-badge {
  background: #fee2e2 !important;
  color: #dc2626 !important;
}

.no-action {
  color: #cbd5e0;
  font-size: 13px;
}
</style>
