<template>
  <h2 class="ops-page-title">操作员管理</h2>

  <div class="ops-card">
    <div class="ops-toolbar">
      <a-input
        v-model:value="filter.keyword"
        placeholder="搜索账号 / 姓名 / 邮箱"
        style="width: 240px"
        allow-clear
        @press-enter="reload"
        @change="onKeywordChange"
      />
      <a-select
        v-model:value="filter.status"
        style="width: 140px"
        :options="statusOptions"
        placeholder="状态"
        allow-clear
        @change="reload"
      />
      <a-button @click="reload">刷新</a-button>
      <span style="flex: 1" />
      <a-button type="primary" @click="openCreate">新增账号</a-button>
    </div>

    <a-table
      :columns="columns"
      :data-source="rows"
      :loading="loading"
      :pagination="pagination"
      row-key="id"
      @change="onTableChange"
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'status'">
          <a-tag :color="record.status === 'active' ? 'green' : 'red'">
            {{ record.status === "active" ? "启用" : "停用" }}
          </a-tag>
        </template>
        <template v-else-if="column.key === 'last_login_at'">
          {{ record.last_login_at ? formatDate(record.last_login_at) : "—" }}
        </template>
        <template v-else-if="column.key === 'created_at'">
          {{ formatDate(record.created_at) }}
        </template>
        <template v-else-if="column.key === 'actions'">
          <div class="table-actions-row">
            <a-tooltip title="重置密码">
              <a-button
                type="text"
                shape="circle"
                size="small"
                class="action-btn action-key"
                @click="openResetPassword(record)"
              >
                <KeyOutlined />
              </a-button>
            </a-tooltip>

            <a-tooltip :title="record.status === 'active' ? '停用账号' : '启用账号'">
              <a-popconfirm
                :title="record.status === 'active' ? '确认停用该账号？' : '确认启用该账号？'"
                :disabled="record.id === auth.operator?.id"
                @confirm="toggleStatus(record)"
              >
                <a-button
                  type="text"
                  shape="circle"
                  size="small"
                  :class="['action-btn', record.status === 'active' ? 'action-revoke' : 'action-play']"
                  :disabled="record.id === auth.operator?.id"
                >
                  <StopOutlined v-if="record.status === 'active'" />
                  <PlayCircleOutlined v-else />
                </a-button>
              </a-popconfirm>
            </a-tooltip>
          </div>
        </template>
      </template>
    </a-table>
  </div>

  <a-modal
    v-model:open="createOpen"
    title="新增账号"
    :confirm-loading="createLoading"
    @ok="submitCreate"
    @cancel="resetCreate"
  >
    <a-form layout="vertical" :model="createForm">
      <a-form-item label="账号" required>
        <a-input v-model:value="createForm.username" placeholder="登录账号" />
      </a-form-item>
      <a-form-item label="姓名" required>
        <a-input v-model:value="createForm.display_name" placeholder="显示名称" />
      </a-form-item>
      <a-form-item label="邮箱">
        <a-input v-model:value="createForm.email" placeholder="可选" />
      </a-form-item>
      <a-form-item label="初始密码" required help="至少 8 位">
        <a-input-password v-model:value="createForm.password" placeholder="≥ 8 位" />
      </a-form-item>
    </a-form>
  </a-modal>

  <a-modal
    v-model:open="resetOpen"
    :title="resetTarget ? `重置 ${resetTarget.display_name} 的密码` : '重置密码'"
    :confirm-loading="resetLoading"
    @ok="submitResetPassword"
    @cancel="resetOpen = false"
  >
    <a-form layout="vertical">
      <a-form-item label="新密码" required help="至少 8 位">
        <a-input-password v-model:value="resetPasswordValue" placeholder="≥ 8 位" />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script setup lang="ts">
import { KeyOutlined, StopOutlined, PlayCircleOutlined } from "@ant-design/icons-vue";
import type { TablePaginationConfig } from "ant-design-vue";
import { message } from "ant-design-vue";
import dayjs from "dayjs";
import { computed, onMounted, reactive, ref } from "vue";

import { OpsApiError, http } from "@/lib/http";
import { useAuthStore } from "@/stores/auth";

interface AccountRow {
  id: number;
  username: string;
  display_name: string;
  email: string | null;
  role: string;
  status: string;
  last_login_at: string | null;
  created_at: string;
  updated_at: string;
}

interface ListResult {
  items: AccountRow[];
  total: number;
  page: number;
  size: number;
}

const auth = useAuthStore();

const filter = reactive({
  keyword: "",
  status: undefined as string | undefined,
});

const statusOptions = [
  { label: "启用", value: "active" },
  { label: "停用", value: "disabled" },
];

const columns = [
  { title: "ID", dataIndex: "id", key: "id", width: 80 },
  { title: "账号", dataIndex: "username", key: "username" },
  { title: "姓名", dataIndex: "display_name", key: "display_name" },
  { title: "邮箱", dataIndex: "email", key: "email" },
  { title: "状态", key: "status", width: 100 },
  { title: "最近登录", key: "last_login_at", width: 180 },
  { title: "创建时间", key: "created_at", width: 180 },
  { title: "操作", key: "actions", width: 200 },
];

const rows = ref<AccountRow[]>([]);
const loading = ref(false);
const page = ref(1);
const size = ref(20);
const total = ref(0);

const pagination = computed<TablePaginationConfig>(() => ({
  current: page.value,
  pageSize: size.value,
  total: total.value,
  showSizeChanger: true,
  pageSizeOptions: ["10", "20", "50", "100"],
}));

let keywordTimer: number | null = null;

function onKeywordChange() {
  if (keywordTimer) window.clearTimeout(keywordTimer);
  keywordTimer = window.setTimeout(() => {
    page.value = 1;
    void reload();
  }, 300);
}

async function reload() {
  loading.value = true;
  try {
    const result = await http.get<ListResult>("/accounts", {
      keyword: filter.keyword || undefined,
      status: filter.status || undefined,
      page: page.value,
      size: size.value,
    });
    rows.value = result.items;
    total.value = result.total;
  } catch (error) {
    if (error instanceof OpsApiError) message.error(error.detail || error.message);
  } finally {
    loading.value = false;
  }
}

function onTableChange(pag: TablePaginationConfig) {
  page.value = pag.current ?? 1;
  size.value = pag.pageSize ?? 20;
  void reload();
}

const createOpen = ref(false);
const createLoading = ref(false);
const createForm = reactive({
  username: "",
  display_name: "",
  email: "",
  password: "",
});

function resetCreate() {
  createForm.username = "";
  createForm.display_name = "";
  createForm.email = "";
  createForm.password = "";
  createOpen.value = false;
}

function openCreate() {
  resetCreate();
  createOpen.value = true;
}

async function submitCreate() {
  if (!createForm.username.trim()) {
    message.warning("请输入账号");
    return;
  }
  if (createForm.password.length < 8) {
    message.warning("初始密码至少 8 位");
    return;
  }
  createLoading.value = true;
  try {
    await http.post("/accounts", {
      username: createForm.username.trim(),
      display_name: createForm.display_name.trim() || createForm.username.trim(),
      email: createForm.email.trim(),
      password: createForm.password,
    });
    message.success("新建成功");
    resetCreate();
    void reload();
  } catch (error) {
    if (error instanceof OpsApiError) message.error(error.detail || error.message);
  } finally {
    createLoading.value = false;
  }
}

const resetOpen = ref(false);
const resetLoading = ref(false);
const resetTarget = ref<AccountRow | null>(null);
const resetPasswordValue = ref("");

function openResetPassword(row: AccountRow) {
  resetTarget.value = row;
  resetPasswordValue.value = "";
  resetOpen.value = true;
}

async function submitResetPassword() {
  if (!resetTarget.value) return;
  if (resetPasswordValue.value.length < 8) {
    message.warning("新密码至少 8 位");
    return;
  }
  resetLoading.value = true;
  try {
    await http.post(`/accounts/${resetTarget.value.id}/password`, {
      password: resetPasswordValue.value,
    });
    message.success("重置成功");
    resetOpen.value = false;
  } catch (error) {
    if (error instanceof OpsApiError) message.error(error.detail || error.message);
  } finally {
    resetLoading.value = false;
  }
}

async function toggleStatus(row: AccountRow) {
  const next = row.status === "active" ? "disabled" : "active";
  try {
    await http.post(`/accounts/${row.id}/status`, { status: next });
    message.success(next === "active" ? "已启用" : "已停用");
    void reload();
  } catch (error) {
    if (error instanceof OpsApiError) message.error(error.detail || error.message);
  }
}

function formatDate(value: string | null | undefined): string {
  return value ? dayjs(value).format("YYYY-MM-DD HH:mm:ss") : "—";
}

onMounted(() => {
  void reload();
});
</script>

<style scoped>
.disabled {
  color: #c4c4c4;
  cursor: not-allowed;
  pointer-events: none;
}
</style>
