<script setup lang="ts">
import { NButton, NDataTable, NPopconfirm, useDialog, useMessage, type DataTableColumns } from 'naive-ui'
import { h, ref } from 'vue'

import { clearUserMfa, deleteUser, deleteUserApiKeys, listUsers, resetUserPassword } from '@/api/tenant'
import FootNote from '@/components/FootNote.vue'
import StatusBadge from '@/components/StatusBadge.vue'
import UserFormModal from '@/components/tenant/UserFormModal.vue'
import { fmtTime } from '@/composables/useFormat'
import { useAsync } from '@/composables/useAsync'
import type { IamUser } from '@/types/api'

const props = defineProps<{ cfgId: number }>()

const message = useMessage()
const dialog = useDialog()
const users = useAsync(() => listUsers(props.cfgId))
const showForm = ref(false)
const editingUser = ref<IamUser | null>(null)

function openCreate() {
  editingUser.value = null
  showForm.value = true
}

function openEdit(row: IamUser) {
  editingUser.value = row
  showForm.value = true
}

async function act(fn: () => Promise<unknown>, ok: string) {
  try {
    await fn()
    message.success(ok)
    void users.run()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '操作失败')
  }
}

function confirmDelete(row: IamUser) {
  dialog.warning({
    title: '删除用户',
    content: () =>
      h('div', { class: 'text-[13px]' }, [
        h('p', `确定删除用户「${row.name}」？此操作不可恢复。`),
        h('p', { class: 'mt-1.5 text-ink-3' }, '删除后该用户的全部 API Key 将一并吊销'),
      ]),
    positiveText: '确认删除',
    negativeText: '取消',
    onPositiveClick: () => act(() => deleteUser(props.cfgId, row.id), `已删除用户 ${row.name}`),
  })
}

async function resetPwd(row: IamUser) {
  try {
    const { password } = await resetUserPassword(props.cfgId, row.id)
    dialog.success({
      title: '一次性密码',
      content: () =>
        h('div', [
          h('p', { class: 'mb-2 text-[13px]' }, `${row.name} 的新密码（首次登录须修改）：`),
          h('code', { class: 'mono rounded bg-line-soft px-2 py-1 select-all' }, password),
        ]),
      positiveText: '已保存',
    })
  } catch (e) {
    message.error(e instanceof Error ? e.message : '重置失败')
  }
}

const columns: DataTableColumns<IamUser> = [
  {
    title: '用户',
    key: 'name',
    minWidth: 220,
    render: (row) =>
      h('div', [
        h('div', { class: 'flex items-center gap-2' }, [
          h('span', { class: 'font-medium' }, row.name),
          row.isCurrentUser
            ? h(StatusBadge, { kind: 'snatch', label: '当前签名用户', dot: false })
            : null,
        ]),
        h('div', { class: 'text-xs text-ink-3 mt-px' }, row.email || row.description || '—'),
      ]),
  },
  {
    title: '状态',
    key: 'lifecycleState',
    width: 90,
    render: (row) =>
      h(StatusBadge, {
        kind: row.lifecycleState === 'ACTIVE' ? 'run' : 'stop',
        label: row.lifecycleState === 'ACTIVE' ? '活跃' : row.lifecycleState,
      }),
  },
  {
    title: 'MFA',
    key: 'mfaActivated',
    width: 70,
    render: (row) => h('span', { class: 'text-[13px] tabular-nums' }, row.mfaActivated ? '已启用' : '未启用'),
  },
  {
    title: '创建时间',
    key: 'timeCreated',
    width: 150,
    render: (row) => h('span', { class: 'text-[13px] text-ink-2' }, fmtTime(row.timeCreated)),
  },
  {
    title: '操作',
    key: 'actions',
    width: 290,
    render: (row) =>
      h('div', { class: 'flex items-center gap-1' }, [
        h(NButton, { size: 'tiny', quaternary: true, onClick: () => openEdit(row) }, { default: () => '修改' }),
        h(NButton, { size: 'tiny', quaternary: true, onClick: () => resetPwd(row) }, { default: () => '重置密码' }),
        h(
          NPopconfirm,
          {
            onPositiveClick: () =>
              act(() => clearUserMfa(props.cfgId, row.id), `已清除 ${row.name} 的全部 MFA`),
          },
          {
            trigger: () => h(NButton, { size: 'tiny', quaternary: true }, { default: () => '清 MFA' }),
            default: () => '清除该用户全部 MFA 因子？',
          },
        ),
        h(
          NPopconfirm,
          {
            onPositiveClick: () =>
              act(() => deleteUserApiKeys(props.cfgId, row.id), `已删除 ${row.name} 的 API Key`),
          },
          {
            trigger: () => h(NButton, { size: 'tiny', quaternary: true }, { default: () => '删 Key' }),
            default: () => '删除该用户全部 API Key（跳过当前配置使用中的指纹）？',
          },
        ),
        row.isCurrentUser
          ? null
          : h(
              NButton,
              { size: 'tiny', quaternary: true, type: 'error', onClick: () => confirmDelete(row) },
              { default: () => '删除' },
            ),
      ]),
  },
]
</script>

<template>
  <div class="panel">
    <div class="flex items-center justify-between border-b border-line-soft px-4.5 py-3.5">
      <div class="text-sm font-semibold">IAM 用户</div>
      <NButton size="small" type="primary" @click="openCreate">添加用户</NButton>
    </div>
    <NDataTable
      :columns="columns"
      :data="users.data.value ?? []"
      :loading="users.loading.value"
      :scroll-x="800"
      :row-key="(r: IamUser) => r.id"
    />
    <FootNote>
      重置密码生成一次性密码，用户首次登录须修改；当前配置签名用户不可删除，避免面板失联
    </FootNote>

    <UserFormModal
      v-model:show="showForm"
      :cfg-id="cfgId"
      :user="editingUser"
      @created="users.run()"
    />
  </div>
</template>
