<script setup lang="ts">
interface UserRow {
  id: number
  username: string
  email: string | null
  nickname: string | null
  avatar: string | null
  role: string
  status: string
  createdAt: Date | null
}

const currentPage = ref(1)
const pageSize = ref(10)
const searchQuery = ref("")

const { data, refresh, pending } = await useHttpFetch("/api/users", {
  query: computed(() => ({
    page: currentPage.value,
    pageSize: pageSize.value,
    search: searchQuery.value || undefined,
  })),
  watch: [currentPage, pageSize, searchQuery],
})

const userList = computed<UserRow[]>(() => (data.value as any)?.list ?? [])
const totalUsers = computed(() => (data.value as any)?.total ?? 0)
const totalPages = computed(() => (data.value as any)?.totalPages ?? 1)

// Create modal state
const showCreateModal = ref(false)
const createForm = ref({
  username: "",
  password: "",
  email: "",
  role: "user" as "user" | "admin",
})
const createLoading = ref(false)
const createError = ref("")

// Delete confirmation
const deletingId = ref<number | null>(null)

function roleBadge(role: string) {
  const map: Record<string, { label: string; class: string }> = {
    admin: { label: "管理员", class: "role-admin" },
    user: { label: "用户", class: "role-user" },
  }
  return map[role] ?? { label: role, class: "role-user" }
}

function statusBadge(status: string) {
  const map: Record<string, { label: string; class: string }> = {
    active: { label: "正常", class: "status-active" },
    disabled: { label: "禁用", class: "status-disabled" },
  }
  return map[status] ?? { label: status, class: "status-disabled" }
}

function formatDate(date: Date | null) {
  if (!date) return "-"
  return new Intl.DateTimeFormat("zh-CN", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date(date))
}

async function handleDelete(id: number) {
  if (!confirm("确定删除此用户？此操作不可撤销。")) return
  deletingId.value = id
  try {
    await $fetch(`/api/users/${id}`, { method: "DELETE" })
    await refresh()
  } catch (err: any) {
    alert(err?.data?.statusMessage || "删除失败")
  } finally {
    deletingId.value = null
  }
}

async function handleCreate() {
  createError.value = ""
  if (!createForm.value.username || !createForm.value.password) {
    createError.value = "用户名和密码不能为空"
    return
  }
  createLoading.value = true
  try {
    await $fetch("/api/users", {
      method: "POST",
      body: createForm.value,
    })
    showCreateModal.value = false
    createForm.value = { username: "", password: "", email: "", role: "user" }
    currentPage.value = 1
    await refresh()
  } catch (err: any) {
    createError.value = err?.data?.statusMessage || "创建失败"
  } finally {
    createLoading.value = false
  }
}

function openCreate() {
  createError.value = ""
  createForm.value = { username: "", password: "", email: "", role: "user" }
  showCreateModal.value = true
}

function closeModal() {
  showCreateModal.value = false
}

function goToPage(page: number) {
  if (page < 1 || page > totalPages.value) return
  currentPage.value = page
}
</script>

<template>
  <div class="users-page">
    <header class="page-header">
      <div class="page-header-content">
        <h1 class="page-title">用户管理</h1>
        <p class="page-subtitle">管理系统用户账户</p>
      </div>
      <div class="header-actions">
        <div class="search-box">
          <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
            <circle cx="11" cy="11" r="8" />
            <path d="M21 21l-4.35-4.35" stroke-linecap="round" />
          </svg>
          <input
            v-model="searchQuery"
            type="text"
            placeholder="搜索用户名、邮箱..."
            class="search-input"
            @keyup.enter="currentPage = 1"
          />
        </div>
        <button class="btn-primary" @click="openCreate">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <line x1="12" y1="5" x2="12" y2="19" stroke-linecap="round" />
            <line x1="5" y1="12" x2="19" y2="12" stroke-linecap="round" />
          </svg>
          新增用户
        </button>
      </div>
    </header>

    <!-- Stats bar -->
    <div class="stats-grid">
      <div class="stat-card">
        <div class="stat-label">用户总数</div>
        <div class="stat-value">{{ totalUsers }}</div>
      </div>
      <div class="stat-card">
        <div class="stat-label">管理员</div>
        <div class="stat-value">
          {{ userList.filter((u) => u.role === "admin").length }}
        </div>
      </div>
      <div class="stat-card">
        <div class="stat-label">已禁用</div>
        <div class="stat-value">
          {{ userList.filter((u) => u.status === "disabled").length }}
        </div>
      </div>
    </div>

    <!-- User table -->
    <div class="table-card">
      <table class="data-table">
        <thead>
          <tr>
            <th class="text-left">用户</th>
            <th class="text-left">邮箱</th>
            <th class="text-left">角色</th>
            <th class="text-left">状态</th>
            <th class="text-left">注册时间</th>
            <th class="text-right">操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-if="pending">
            <td colspan="6" class="text-center">加载中...</td>
          </tr>
          <tr v-else-if="userList.length === 0">
            <td colspan="6" class="text-center">暂无用户</td>
          </tr>
          <tr v-for="u in userList" :key="u.id" class="table-row">
            <td class="user-cell">
              <div class="user-info">
                <div class="user-avatar">
                  <img v-if="u.avatar" :src="u.avatar" :alt="u.username" />
                  <span v-else class="avatar-placeholder">
                    {{ u.username.charAt(0).toUpperCase() }}
                  </span>
                </div>
                <div class="user-details">
                  <span class="user-name">{{ u.nickname || u.username }}</span>
                  <span class="user-username">@{{ u.username }}</span>
                </div>
              </div>
            </td>
            <td class="email-cell">{{ u.email || "-" }}</td>
            <td class="role-cell">
              <span :class="['role-badge', roleBadge(u.role).class]">
                {{ roleBadge(u.role).label }}
              </span>
            </td>
            <td class="status-cell">
              <span :class="['status-badge', statusBadge(u.status).class]">
                {{ statusBadge(u.status).label }}
              </span>
            </td>
            <td class="date-cell">{{ formatDate(u.createdAt) }}</td>
            <td class="actions-cell">
              <button
                class="action-btn action-btn-danger"
                :disabled="deletingId === u.id"
                @click="handleDelete(u.id)"
              >
                {{ deletingId === u.id ? "删除中..." : "删除" }}
              </button>
            </td>
          </tr>
        </tbody>
      </table>

      <!-- Pagination -->
      <div v-if="totalPages > 1" class="pagination">
        <button
          class="page-btn"
          :disabled="currentPage === 1"
          @click="goToPage(currentPage - 1)"
        >
          上一页
        </button>
        <div class="page-info">
          第 {{ currentPage }} / {{ totalPages }} 页，共 {{ totalUsers }} 条
        </div>
        <button
          class="page-btn"
          :disabled="currentPage === totalPages"
          @click="goToPage(currentPage + 1)"
        >
          下一页
        </button>
      </div>
    </div>

    <!-- Create Modal -->
    <Teleport to="body">
      <div v-if="showCreateModal" class="modal-overlay" @click.self="closeModal">
        <div class="modal-card">
          <div class="modal-header">
            <h3 class="modal-title">新增用户</h3>
            <button class="modal-close" @click="closeModal">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <line x1="18" y1="6" x2="6" y2="18" stroke-linecap="round" />
                <line x1="6" y1="6" x2="18" y2="18" stroke-linecap="round" />
              </svg>
            </button>
          </div>
          <form class="modal-body" @submit.prevent="handleCreate">
            <div v-if="createError" class="form-error">{{ createError }}</div>
            <div class="form-group">
              <label class="form-label">用户名</label>
              <input
                v-model="createForm.username"
                type="text"
                class="form-input"
                placeholder="3-20个字符，字母数字下划线"
              />
            </div>
            <div class="form-group">
              <label class="form-label">密码</label>
              <input
                v-model="createForm.password"
                type="password"
                class="form-input"
                placeholder="至少6位"
              />
            </div>
            <div class="form-group">
              <label class="form-label">邮箱（选填）</label>
              <input
                v-model="createForm.email"
                type="email"
                class="form-input"
                placeholder="example@domain.com"
              />
            </div>
            <div class="form-group">
              <label class="form-label">角色</label>
              <select v-model="createForm.role" class="form-select">
                <option value="user">普通用户</option>
                <option value="admin">管理员</option>
              </select>
            </div>
            <div class="modal-footer">
              <button type="button" class="btn-secondary" @click="closeModal">
                取消
              </button>
              <button type="submit" class="btn-primary" :disabled="createLoading">
                {{ createLoading ? "创建中..." : "创建" }}
              </button>
            </div>
          </form>
        </div>
      </div>
    </Teleport>
  </div>
</template>

<style scoped>
.users-page {
  padding: 40px;
}

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 32px;
}

.page-title {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 400;
  color: var(--color-ink);
  letter-spacing: -0.3px;
  margin: 0 0 6px 0;
}

.page-subtitle {
  font-size: 15px;
  color: var(--color-muted);
  margin: 0;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.search-box {
  position: relative;
  display: flex;
  align-items: center;
}

.search-icon {
  position: absolute;
  left: 12px;
  width: 18px;
  height: 18px;
  color: var(--color-muted);
  pointer-events: none;
}

.search-input {
  padding: 10px 14px 10px 40px;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: 8px;
  font-size: 14px;
  color: var(--color-ink);
  width: 240px;
  transition: all 0.15s ease;
}

.search-input::placeholder {
  color: var(--color-muted);
}

.search-input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(204, 120, 92, 0.15);
}

.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  background: var(--color-primary);
  color: var(--color-on-primary);
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s ease;
}

.btn-primary:hover {
  background: var(--color-primary-active);
}

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

.btn-primary svg {
  width: 16px;
  height: 16px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 32px;
}

.stat-card {
  background: var(--color-surface-card);
  border-radius: 12px;
  padding: 20px;
}

.stat-label {
  font-size: 13px;
  color: var(--color-muted);
  font-weight: 500;
  margin-bottom: 4px;
}

.stat-value {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 400;
  color: var(--color-ink);
  line-height: 1;
}

.table-card {
  background: var(--color-surface-card);
  border-radius: 12px;
  overflow: hidden;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
}

.data-table th {
  padding: 14px 16px;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--color-surface-soft);
  border-bottom: 1px solid var(--color-hairline);
  text-align: left;
}

.data-table td {
  padding: 14px 16px;
  font-size: 14px;
  color: var(--color-body-strong);
  border-bottom: 1px solid var(--color-hairline);
}

.table-row:last-child td {
  border-bottom: none;
}

.table-row:hover td {
  background: var(--color-surface-soft);
}

.user-cell {
  min-width: 200px;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--color-surface-soft);
  display: flex;
  align-items: center;
  justify-content: center;
}

.user-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-placeholder {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-muted);
}

.user-details {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.user-name {
  font-weight: 500;
  color: var(--color-ink);
  font-size: 14px;
}

.user-username {
  font-size: 12px;
  color: var(--color-muted);
}

.email-cell {
  color: var(--color-muted);
  font-size: 13px;
}

.date-cell {
  font-size: 13px;
  color: var(--color-muted);
}

.role-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 9999px;
  font-size: 12px;
  font-weight: 500;
}

.role-admin {
  background: rgba(204, 120, 92, 0.15);
  color: var(--color-primary);
}

.role-user {
  background: rgba(93, 184, 166, 0.15);
  color: var(--color-accent-teal);
}

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

.status-active {
  background: rgba(93, 184, 166, 0.15);
  color: var(--color-accent-teal);
}

.status-disabled {
  background: var(--color-hairline);
  color: var(--color-muted);
}

.actions-cell {
  text-align: right;
}

.action-btn {
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-muted);
  background: transparent;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.action-btn:hover {
  background: var(--color-hairline);
  color: var(--color-ink);
}

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

.action-btn-danger:hover {
  background: rgba(198, 69, 69, 0.1);
  color: #c64545;
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 16px;
  border-top: 1px solid var(--color-hairline);
}

.page-btn {
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-ink);
  background: var(--color-surface-soft);
  border: 1px solid var(--color-hairline);
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.page-btn:hover:not(:disabled) {
  background: var(--color-hairline);
}

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

.page-info {
  font-size: 13px;
  color: var(--color-muted);
}

/* Modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-card {
  background: var(--color-canvas);
  border-radius: 12px;
  width: 100%;
  max-width: 440px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid var(--color-hairline);
}

.modal-title {
  font-size: 18px;
  font-weight: 500;
  color: var(--color-ink);
  margin: 0;
}

.modal-close {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  color: var(--color-muted);
  transition: all 0.15s ease;
}

.modal-close:hover {
  background: var(--color-surface-soft);
  color: var(--color-ink);
}

.modal-close svg {
  width: 18px;
  height: 18px;
}

.modal-body {
  padding: 24px;
}

.form-error {
  padding: 10px 14px;
  background: rgba(198, 69, 69, 0.1);
  border: 1px solid rgba(198, 69, 69, 0.2);
  border-radius: 6px;
  color: #c64545;
  font-size: 13px;
  margin-bottom: 16px;
}

.form-group {
  margin-bottom: 16px;
}

.form-label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-body-strong);
  margin-bottom: 6px;
}

.form-input,
.form-select {
  width: 100%;
  padding: 10px 14px;
  background: var(--color-canvas);
  border: 1px solid var(--color-hairline);
  border-radius: 8px;
  font-size: 14px;
  color: var(--color-ink);
  transition: all 0.15s ease;
  box-sizing: border-box;
}

.form-input:focus,
.form-select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(204, 120, 92, 0.15);
}

.form-input::placeholder {
  color: var(--color-muted);
}

.modal-footer {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  padding-top: 8px;
}

.btn-secondary {
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-body-strong);
  background: var(--color-surface-soft);
  border: 1px solid var(--color-hairline);
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.btn-secondary:hover {
  background: var(--color-hairline);
}

@media (max-width: 1024px) {
  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .users-page {
    padding: 24px;
  }

  .page-header {
    flex-direction: column;
    gap: 16px;
  }

  .header-actions {
    flex-direction: column;
    width: 100%;
  }

  .search-input {
    width: 100%;
  }

  .stats-grid {
    grid-template-columns: 1fr;
  }
}
</style>
