<template>
  <AppShell>
    <div class="space-y-4">
      <div class="flex justify-between items-center">
        <h2 class="text-lg font-semibold">
          用户管理
        </h2>
        <NButton
          type="primary"
          @click="openCreate"
        >
          + 新增用户
        </NButton>
      </div>
      <NDataTable
        :data="users"
        :columns="columns"
        :row-key="(row: AdminUser) => row.id"
        :loading="loading"
      />

      <!-- 新增用户 -->
      <NModal
        v-model:show="showCreate"
        preset="card"
        title="新增用户"
        style="width: 480px"
      >
        <NForm>
          <NFormItem label="邮箱">
            <NInput
              v-model:value="createForm.email"
              placeholder="user@example.com"
            />
          </NFormItem>
          <NFormItem label="显示名">
            <NInput v-model:value="createForm.display_name" />
          </NFormItem>
          <NFormItem label="初始密码（至少 8 位）">
            <NInput
              v-model:value="createForm.password"
              type="password"
              show-password-on="click"
            />
          </NFormItem>
          <NFormItem label="管理员">
            <NSwitch v-model:value="createForm.is_admin" />
          </NFormItem>
        </NForm>
        <template #footer>
          <div class="flex justify-end gap-2">
            <NButton @click="showCreate = false">
              取消
            </NButton>
            <NButton
              type="primary"
              :loading="creating"
              :disabled="!canCreate"
              @click="doCreate"
            >
              创建
            </NButton>
          </div>
        </template>
      </NModal>

      <!-- 编辑显示名 -->
      <NModal
        v-model:show="showEdit"
        preset="card"
        title="编辑用户"
        style="width: 420px"
      >
        <NForm>
          <NFormItem label="显示名">
            <NInput v-model:value="editName" />
          </NFormItem>
        </NForm>
        <template #footer>
          <div class="flex justify-end gap-2">
            <NButton @click="showEdit = false">
              取消
            </NButton>
            <NButton
              type="primary"
              :loading="saving"
              @click="doEdit"
            >
              保存
            </NButton>
          </div>
        </template>
      </NModal>

      <!-- 临时密码展示 -->
      <NModal
        v-model:show="showTemp"
        preset="card"
        title="密码已重置"
        style="width: 480px"
      >
        <NAlert
          type="warning"
          :bordered="false"
        >
          请立即复制临时密码并交给用户，关闭后无法再次查看。用户登录后应尽快自助改密。
        </NAlert>
        <NInput
          :value="tempPassword"
          readonly
          class="mt-3"
        />
        <template #footer>
          <div class="flex justify-end">
            <NButton @click="copyTemp">
              复制
            </NButton>
          </div>
        </template>
      </NModal>
    </div>
  </AppShell>
</template>

<script setup lang="ts">
import { computed, h, onMounted, ref } from 'vue'
import {
  NAlert,
  NButton,
  NDataTable,
  NForm,
  NFormItem,
  NInput,
  NModal,
  NSpace,
  NSwitch,
  NTag,
  useDialog,
  useMessage,
} from 'naive-ui'
import type { DataTableColumns } from 'naive-ui'

import AppShell from '@/layouts/AppShell.vue'
import { useAuthStore } from '@/stores/auth'
import { userAdminApi, type AdminUser } from '@/api/usersAdmin'

const auth = useAuthStore()
const msg = useMessage()
const dlg = useDialog()

const users = ref<AdminUser[]>([])
const loading = ref(false)

const showCreate = ref(false)
const creating = ref(false)
const createForm = ref({ email: '', display_name: '', password: '', is_admin: false })
const canCreate = computed(() => {
  const f = createForm.value
  return !!f.email.trim() && !!f.display_name.trim() && f.password.length >= 8
})

const showEdit = ref(false)
const saving = ref(false)
const editName = ref('')
const editTarget = ref<AdminUser | null>(null)

const showTemp = ref(false)
const tempPassword = ref('')

// isSelf 用于禁用对自己的危险操作（降级/禁用/删除），与后端护栏一致。
function isSelf(row: AdminUser): boolean {
  return row.id === auth.user?.id
}

const columns: DataTableColumns<AdminUser> = [
  { title: '邮箱', key: 'email' },
  { title: '显示名', key: 'display_name' },
  {
    title: '角色',
    key: 'is_admin',
    width: 90,
    render: (row) =>
      h(
        NTag,
        { type: row.is_admin ? 'success' : 'default', size: 'small' },
        { default: () => (row.is_admin ? '管理员' : '用户') },
      ),
  },
  {
    title: '状态',
    key: 'enabled',
    width: 90,
    render: (row) =>
      h(
        NTag,
        { type: row.enabled ? 'info' : 'error', size: 'small' },
        { default: () => (row.enabled ? '启用' : '禁用') },
      ),
  },
  {
    title: '创建时间',
    key: 'created_at',
    render: (row) => new Date(row.created_at).toLocaleString(),
  },
  {
    title: '操作',
    key: 'actions',
    width: 360,
    render: (row) =>
      h(NSpace, { size: 'small' }, {
        default: () => [
          h(NButton, { size: 'small', onClick: () => openEdit(row) }, { default: () => '编辑' }),
          h(
            NButton,
            { size: 'small', disabled: isSelf(row), onClick: () => toggleRole(row) },
            { default: () => (row.is_admin ? '取消管理员' : '设为管理员') },
          ),
          h(
            NButton,
            { size: 'small', disabled: isSelf(row), onClick: () => toggleEnabled(row) },
            { default: () => (row.enabled ? '禁用' : '启用') },
          ),
          h(NButton, { size: 'small', onClick: () => resetPassword(row) }, { default: () => '重置密码' }),
          h(
            NButton,
            { size: 'small', type: 'error', disabled: isSelf(row), onClick: () => removeUser(row) },
            { default: () => '删除' },
          ),
        ],
      }),
  },
]

onMounted(reload)

async function reload() {
  loading.value = true
  try {
    users.value = await userAdminApi.list()
  } catch (e: unknown) {
    msg.error((e as Error).message || '加载失败')
  } finally {
    loading.value = false
  }
}

function openCreate() {
  createForm.value = { email: '', display_name: '', password: '', is_admin: false }
  showCreate.value = true
}

async function doCreate() {
  if (!canCreate.value) return
  creating.value = true
  try {
    await userAdminApi.create({
      email: createForm.value.email.trim(),
      display_name: createForm.value.display_name.trim(),
      password: createForm.value.password,
      is_admin: createForm.value.is_admin,
    })
    showCreate.value = false
    msg.success('已创建')
    await reload()
  } catch (e: unknown) {
    msg.error((e as Error).message || '创建失败')
  } finally {
    creating.value = false
  }
}

function openEdit(row: AdminUser) {
  editTarget.value = row
  editName.value = row.display_name
  showEdit.value = true
}

async function doEdit() {
  if (!editTarget.value || !editName.value.trim()) return
  saving.value = true
  try {
    await userAdminApi.updateProfile(editTarget.value.id, editName.value.trim())
    showEdit.value = false
    msg.success('已保存')
    await reload()
  } catch (e: unknown) {
    msg.error((e as Error).message || '保存失败')
  } finally {
    saving.value = false
  }
}

async function toggleRole(row: AdminUser) {
  try {
    await userAdminApi.setRole(row.id, !row.is_admin)
    msg.success('已更新角色')
    // 若修改的是当前登录用户，刷新本地会话以同步 isAdmin，避免缓存陈旧。
    if (row.id === auth.user?.id) {
      await auth.refreshUser().catch(() => {})
    }
    await reload()
  } catch (e: unknown) {
    msg.error((e as Error).message || '操作失败')
  }
}

async function toggleEnabled(row: AdminUser) {
  try {
    await userAdminApi.setEnabled(row.id, !row.enabled)
    msg.success(row.enabled ? '已禁用' : '已启用')
    await reload()
  } catch (e: unknown) {
    msg.error((e as Error).message || '操作失败')
  }
}

function resetPassword(row: AdminUser) {
  dlg.warning({
    title: '重置密码',
    content: `确定要重置 "${row.email}" 的密码吗？将生成新的临时密码并使该用户的全部会话失效。`,
    positiveText: '重置',
    negativeText: '取消',
    onPositiveClick: async () => {
      try {
        const resp = await userAdminApi.resetPassword(row.id)
        tempPassword.value = resp.temp_password
        showTemp.value = true
      } catch (e: unknown) {
        msg.error((e as Error).message || '重置失败')
      }
    },
  })
}

function removeUser(row: AdminUser) {
  dlg.error({
    title: '删除用户',
    content: `确定要删除 "${row.email}" 吗？此操作不可撤销。`,
    positiveText: '删除',
    negativeText: '取消',
    onPositiveClick: async () => {
      try {
        await userAdminApi.remove(row.id)
        msg.success('已删除')
        await reload()
      } catch (e: unknown) {
        msg.error((e as Error).message || '删除失败')
      }
    },
  })
}

function copyTemp() {
  navigator.clipboard.writeText(tempPassword.value).then(
    () => msg.success('已复制'),
    () => msg.error('复制失败'),
  )
}
</script>
