<script setup lang="ts">
import {
  CheckCircle2,
  Clock3,
  Loader2,
  ScrollText,
  Search,
  XCircle,
} from "@lucide/vue";
import { computed, onMounted, reactive, ref } from "vue";

import { ApiError } from "../api/http";
import { listOperationLogs } from "../api/operationLogs";
import type { OperationLog, OperationLogListResponse } from "../api/types";
import StatCard from "../components/StatCard.vue";

const loading = ref(false);
const errorMessage = ref("");
const page = ref(1);
const pageSize = ref(20);
const response = ref<OperationLogListResponse>({
  items: [],
  total: 0,
  page: 1,
  page_size: 20,
});

const filters = reactive({
  keyword: "",
  username: "",
  module: "",
  action: "",
  status: "",
});

const moduleOptions = [
  { value: "", label: "全部模块" },
  { value: "auth", label: "认证" },
  { value: "payroll", label: "工资" },
  { value: "system", label: "系统" },
];

const actionOptions = [
  { value: "", label: "全部动作" },
  { value: "login", label: "用户登录" },
  { value: "profile.update", label: "修改资料" },
  { value: "avatar.update", label: "修改头像" },
  { value: "password.change", label: "修改密码" },
  { value: "user.create", label: "创建用户" },
  { value: "user.list", label: "查看用户" },
  { value: "employee.list", label: "查看员工" },
  { value: "employee.page", label: "分页员工" },
  { value: "employee.create", label: "新增员工" },
  { value: "employee.update", label: "更新员工" },
  { value: "salary_profile.list", label: "查看薪资" },
  { value: "salary_profile.upsert", label: "保存薪资" },
  { value: "payroll.excel.calculate", label: "Excel计算" },
  { value: "payroll.dingtalk.calculate", label: "钉钉计算" },
  { value: "payroll.job.view", label: "查看任务" },
  { value: "payroll.file.download", label: "下载结果" },
  { value: "operation_log.view", label: "查看日志" },
];

const logs = computed(() => response.value.items);
const totalPages = computed(() => Math.max(1, Math.ceil(response.value.total / pageSize.value)));
const successCount = computed(() => logs.value.filter((log) => log.status === "success").length);
const failedCount = computed(() => logs.value.filter((log) => log.status === "failed").length);
const latestLogAction = computed(() => (logs.value[0] ? actionLabel(logs.value[0].action) : "暂无"));

onMounted(loadLogs);

async function loadLogs(): Promise<void> {
  loading.value = true;
  errorMessage.value = "";
  try {
    response.value = await listOperationLogs({
      page: page.value,
      page_size: pageSize.value,
      keyword: filters.keyword.trim(),
      username: filters.username.trim(),
      module: filters.module,
      action: filters.action,
      status: filters.status,
    });
    page.value = response.value.page;
    pageSize.value = response.value.page_size;
  } catch (error) {
    errorMessage.value = error instanceof ApiError ? error.message : "操作日志加载失败";
  } finally {
    loading.value = false;
  }
}

function searchLogs(): void {
  page.value = 1;
  loadLogs();
}

function resetFilters(): void {
  Object.assign(filters, {
    keyword: "",
    username: "",
    module: "",
    action: "",
    status: "",
  });
  searchLogs();
}

function previousPage(): void {
  if (page.value <= 1) {
    return;
  }
  page.value -= 1;
  loadLogs();
}

function nextPage(): void {
  if (page.value >= totalPages.value) {
    return;
  }
  page.value += 1;
  loadLogs();
}

function formatDate(value: string): string {
  return new Date(value).toLocaleString();
}

function moduleLabel(module: string): string {
  return moduleOptions.find((item) => item.value === module)?.label || module || "-";
}

function actionLabel(action: string): string {
  return actionOptions.find((item) => item.value === action)?.label || action || "-";
}

function roleLabel(role: string): string {
  const labels: Record<string, string> = {
    superuser: "超级用户",
    manager: "管理者",
    viewer: "查看权限",
  };
  return labels[role] || role || "匿名";
}

function statusLabel(status: string): string {
  return status === "success" ? "成功" : "失败";
}

function statusClass(status: string): string {
  return status === "success" ? "green" : "red";
}

function targetLabel(log: OperationLog): string {
  if (!log.target_type && !log.target_id) {
    return "-";
  }
  return [log.target_type, log.target_id].filter(Boolean).join(" / ");
}
</script>

<template>
  <div class="view-stack">
    <header class="page-header">
      <div>
        <h1>操作日志</h1>
        <p>查看登录、工资计算、用户管理和下载等关键操作。</p>
      </div>
    </header>

    <section class="summary-strip">
      <StatCard title="日志总数" :value="String(response.total)" :icon="ScrollText" tone="blue" meta="全部记录" />
      <StatCard title="本页成功" :value="String(successCount)" :icon="CheckCircle2" tone="green" meta="当前筛选" />
      <StatCard title="本页失败" :value="String(failedCount)" :icon="XCircle" tone="red" meta="当前筛选" />
      <StatCard title="最新操作" :value="latestLogAction" :icon="Clock3" tone="neutral" meta="当前页" />
    </section>

    <section class="panel">
      <div class="panel-header">
        <div>
          <h2>筛选条件</h2>
          <p>按操作人、模块、动作、状态或关键字查询</p>
        </div>
      </div>
      <form class="form-grid log-filter-form" @submit.prevent="searchLogs">
        <label class="field">
          <span>关键字</span>
          <input v-model="filters.keyword" type="search" placeholder="动作、对象、详情..." />
        </label>
        <label class="field">
          <span>操作人</span>
          <input v-model="filters.username" type="text" placeholder="用户名" />
        </label>
        <label class="field">
          <span>模块</span>
          <select v-model="filters.module">
            <option v-for="item in moduleOptions" :key="item.value" :value="item.value">{{ item.label }}</option>
          </select>
        </label>
        <label class="field">
          <span>动作</span>
          <select v-model="filters.action">
            <option v-for="item in actionOptions" :key="item.value" :value="item.value">{{ item.label }}</option>
          </select>
        </label>
        <label class="field">
          <span>状态</span>
          <select v-model="filters.status">
            <option value="">全部状态</option>
            <option value="success">成功</option>
            <option value="failed">失败</option>
          </select>
        </label>
        <div class="form-actions align-right span-row">
          <button class="secondary-button" type="button" :disabled="loading" @click="resetFilters">重置</button>
          <button class="primary-button" type="submit" :disabled="loading">
            <Loader2 v-if="loading" class="spin" :size="18" aria-hidden="true" />
            <Search v-else :size="18" aria-hidden="true" />
            <span>{{ loading ? "查询中" : "查询" }}</span>
          </button>
        </div>
      </form>
      <p v-if="errorMessage" class="form-error">{{ errorMessage }}</p>
    </section>

    <section class="panel table-panel">
      <div class="panel-header">
        <div>
          <h2>日志列表</h2>
          <p>第 {{ page }} / {{ totalPages }} 页，共 {{ response.total }} 条</p>
        </div>
      </div>
      <div class="table-wrap">
        <table class="data-table operation-log-table">
          <thead>
            <tr>
              <th>时间</th>
              <th>操作人</th>
              <th>模块/动作</th>
              <th>对象</th>
              <th>状态</th>
              <th>来源</th>
              <th>详情</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="log in logs" :key="log.id">
              <td class="mono">{{ formatDate(log.created_at) }}</td>
              <td>
                <strong>{{ log.username || "匿名" }}</strong>
                <span>{{ roleLabel(log.role) }}</span>
              </td>
              <td>
                <strong>{{ moduleLabel(log.module) }}</strong>
                <span>{{ actionLabel(log.action) }}</span>
              </td>
              <td class="mono">{{ targetLabel(log) }}</td>
              <td>
                <span class="status-chip" :class="statusClass(log.status)">{{ statusLabel(log.status) }}</span>
              </td>
              <td>
                <strong>{{ log.ip_address || "-" }}</strong>
                <span :title="log.user_agent">{{ log.user_agent || "-" }}</span>
              </td>
              <td class="log-detail-cell" :title="log.detail">{{ log.detail || "-" }}</td>
            </tr>
          </tbody>
        </table>
      </div>
      <div v-if="!logs.length && !loading" class="empty-state">
        <p>暂无操作日志</p>
      </div>
      <div class="form-actions align-right">
        <button class="secondary-button" type="button" :disabled="loading || page <= 1" @click="previousPage">
          上一页
        </button>
        <button class="secondary-button" type="button" :disabled="loading || page >= totalPages" @click="nextPage">
          下一页
        </button>
      </div>
    </section>
  </div>
</template>
