<template>
  <div>
    <h2 class="h4 mb-4">知识库操作日志</h2>

    <!-- 筛选区 -->
    <div class="card card-body mb-4 shadow-sm">
      <div class="row g-2 align-items-end">
        <div class="col-6 col-md-3">
          <label class="form-label small mb-0">操作类型</label>
          <select v-model="filter.action" class="form-select form-select-sm">
            <option value="">全部</option>
            <option value="upload">upload（上传）</option>
            <option value="download">download（下载）</option>
            <option value="delete">delete（删除）</option>
            <option value="create_kb">create_kb（创建知识库）</option>
            <option value="delete_kb">delete_kb（删除知识库）</option>
            <option value="permission_change">permission_change（权限变更）</option>
          </select>
        </div>
        <div class="col-6 col-md-2">
          <label class="form-label small mb-0">操作者 ID</label>
          <input v-model.number="filter.actor_id" type="number" class="form-control form-control-sm" placeholder="留空=全部" />
        </div>
        <div class="col-6 col-md-2">
          <label class="form-label small mb-0">知识库 ID</label>
          <input v-model.number="filter.kb_id" type="number" class="form-control form-control-sm" placeholder="留空=全部" />
        </div>
        <div class="col-auto d-flex gap-2">
          <button class="btn btn-sm btn-primary" @click="applyFilter">搜索</button>
          <button class="btn btn-sm btn-outline-secondary" @click="resetFilter">重置</button>
        </div>
      </div>
    </div>

    <div v-if="loading" class="text-muted">加载中…</div>
    <div v-else>
      <div class="table-responsive">
        <table class="table table-sm table-hover bg-white shadow-sm align-middle small">
          <thead class="table-light">
            <tr>
              <th>时间</th>
              <th>操作者</th>
              <th>操作</th>
              <th>被操作用户</th>
              <th>部门</th>
              <th>知识库</th>
              <th>文件</th>
              <th>IP</th>
              <th>详情</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="r in items" :key="r.id">
              <td class="text-nowrap text-muted">{{ fmt(r.created_at) }}</td>
              <td>
                <span class="fw-semibold">{{ r.actor_name || r.actor_id }}</span>
              </td>
              <td>
                <span class="badge" :class="actionBadge(r.action)">{{ r.action }}</span>
              </td>
              <td>{{ r.target_name || (r.target_user_id ? '#' + r.target_user_id : '—') }}</td>
              <td>{{ r.department_name || (r.department_id ? '#' + r.department_id : '—') }}</td>
              <td>{{ r.kb_name || (r.kb_id ? '#' + r.kb_id : '—') }}</td>
              <td class="text-truncate" style="max-width:140px" :title="r.file_name">
                {{ r.file_name || '—' }}
              </td>
              <td>{{ r.ip || '—' }}</td>
              <td>
                <span v-if="r.metadata" class="text-muted small">{{ metaStr(r.metadata) }}</span>
                <span v-else>—</span>
              </td>
            </tr>
          </tbody>
        </table>
        <p v-if="!items.length" class="text-muted small">暂无日志记录。</p>
      </div>

      <!-- 分页 -->
      <nav v-if="total > pageSize" class="mt-2">
        <ul class="pagination pagination-sm">
          <li class="page-item" :class="{ disabled: page <= 1 }">
            <a class="page-link" href="#" @click.prevent="page > 1 && page-- && load()">上一页</a>
          </li>
          <li class="page-item disabled">
            <span class="page-link">{{ page }} / {{ totalPages }}（共 {{ total }} 条）</span>
          </li>
          <li class="page-item" :class="{ disabled: page >= totalPages }">
            <a class="page-link" href="#" @click.prevent="page < totalPages && page++ && load()">下一页</a>
          </li>
        </ul>
      </nav>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import http from "../api/http";

const items = ref([]);
const total = ref(0);
const loading = ref(false);
const page = ref(1);
const pageSize = 30;

const filter = reactive({ action: "", actor_id: null, kb_id: null });
const applied = reactive({ action: "", actor_id: null, kb_id: null });

const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize)));

async function load() {
  loading.value = true;
  try {
    const params = { page: page.value, page_size: pageSize };
    if (applied.action) params.action = applied.action;
    if (applied.actor_id) params.actor_id = applied.actor_id;
    if (applied.kb_id) params.kb_id = applied.kb_id;
    const { data } = await http.get("/admin/audit-logs", { params });
    const raw = data?.data;
    items.value = raw?.items || [];
    total.value = raw?.total || 0;
  } catch (e) {
    console.error(e);
  } finally {
    loading.value = false;
  }
}

function applyFilter() {
  Object.assign(applied, filter);
  page.value = 1;
  load();
}

function resetFilter() {
  Object.assign(filter, { action: "", actor_id: null, kb_id: null });
  Object.assign(applied, { action: "", actor_id: null, kb_id: null });
  page.value = 1;
  load();
}

function fmt(t) {
  if (!t) return "—";
  try { return new Date(t).toLocaleString("zh-CN"); } catch { return t; }
}

function actionBadge(action) {
  const m = {
    upload: "bg-success",
    download: "bg-info text-dark",
    delete: "bg-danger",
    archive: "bg-secondary",
    create_kb: "bg-primary",
    delete_kb: "bg-danger",
    permission_change: "bg-warning text-dark",
  };
  return m[action] || "bg-secondary";
}

function metaStr(meta) {
  if (!meta) return "";
  try {
    const obj = typeof meta === "string" ? JSON.parse(meta) : meta;
    return Object.entries(obj)
      .map(([k, v]) => `${k}=${JSON.stringify(v)}`)
      .join("  ");
  } catch {
    return String(meta);
  }
}

onMounted(load);
</script>
