<script setup lang="ts">
import { ref, onMounted, onActivated, watch } from 'vue';
import { useAdminLocale } from '../composables/useAdminLocale';
import { useAuditLabels } from '../utils/audit-labels';
import api from '../api';
import AdminTableEmpty from './AdminTableEmpty.vue';

const props = withDefaults(
  defineProps<{
    endpoint?: string;
    showModuleColumn?: boolean;
    showModuleFilter?: boolean;
  }>(),
  {
    endpoint: '/admin/audit-logs',
    showModuleColumn: true,
    showModuleFilter: true,
  },
);

const { t, locale, localeTag } = useAdminLocale();
const { auditActionLabel, auditModuleLabel } = useAuditLabels();

interface AuditRow {
  action: string;
  module: string;
  targetId: string | null;
  operatorId: string | null;
  operatorUsername: string | null;
  operatorRole: string | null;
  operatorUserType: string | null;
  operatorType: string;
  ipAddress: string | null;
  createdAt: string;
}

const logs = ref<AuditRow[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(10);
const filterModule = ref('');
const loading = ref(false);

onMounted(() => void load());
onActivated(() => {
  if (logs.value.length > 0) void load({ silent: true });
});

watch(
  () => props.endpoint,
  () => {
    page.value = 1;
    load();
  },
);

async function load(opts?: { silent?: boolean }) {
  if (!opts?.silent) loading.value = true;
  try {
  const { data } = await api.get(props.endpoint, {
    params: {
      page: page.value,
      pageSize: pageSize.value,
      module: props.showModuleFilter && filterModule.value.trim()
        ? filterModule.value.trim()
        : undefined,
    },
  });
  logs.value = (data.data.items ?? []) as AuditRow[];
  total.value = data.data.total ?? 0;
  } finally {
    if (!opts?.silent) loading.value = false;
  }
}

function onPageChange(p: number) {
  page.value = p;
  load();
}

function onSizeChange(size: number) {
  pageSize.value = size;
  page.value = 1;
  load();
}

function formatTime(v: string) {
  return new Date(v).toLocaleString(localeTag.value, {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  });
}

function operatorRoleLabel(row: AuditRow): string | null {
  const code = row.operatorRole;
  if (code === 'SUPER_ADMIN') return t('role.super_admin');
  if (code === 'MATCH_ADMIN') return t('role.match_admin');
  if (code === 'FINANCE_ADMIN') return t('role.finance_admin');
  if (code === 'SUPPORT') return t('role.support');
  if (row.operatorUserType === 'ADMIN' || row.operatorType === 'ADMIN') return t('role.admin');
  if (row.operatorUserType === 'AGENT' || row.operatorType === 'AGENT') return t('role.agent');
  if (row.operatorUserType === 'PLAYER' || row.operatorType === 'PLAYER') return t('audit.operator_player');
  return null;
}

function operatorDisplay(row: AuditRow): string {
  if (row.operatorUsername) return row.operatorUsername;
  if (row.operatorType === 'SYSTEM') return t('audit.operator_system');
  return '—';
}
</script>

<template>
  <el-card v-if="showModuleFilter" class="filter-card" shadow="never">
    <el-form inline>
      <el-form-item :label="t('common.module')">
        <el-input
          v-model="filterModule"
          :placeholder="t('audit.module_ph')"
          clearable
          style="width: 160px"
          @keyup.enter="load"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="load">{{ t('common.search') }}</el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <el-card v-loading="loading" class="data-card" shadow="never">
    <div class="table-wrap">
      <el-table :key="locale" :data="logs" stripe>
        <template #empty>
          <AdminTableEmpty />
        </template>
        <el-table-column type="index" :index="(i: number) => (page - 1) * pageSize + i + 1" :label="t('common.seq')" width="70" align="center" fixed="left" />
        <el-table-column :label="t('audit.col.time')" min-width="168" fixed="left">
          <template #default="{ row }">{{ formatTime(row.createdAt) }}</template>
        </el-table-column>
        <el-table-column :label="t('audit.col.operator')" min-width="160">
          <template #default="{ row }">
            <div class="operator-cell">
              <span class="operator-name">{{ operatorDisplay(row) }}</span>
              <span v-if="operatorRoleLabel(row)" class="operator-role">{{ operatorRoleLabel(row) }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column :label="t('audit.col.action')" min-width="140">
          <template #default="{ row }">{{ auditActionLabel(row.action) }}</template>
        </el-table-column>
        <el-table-column
          v-if="showModuleColumn"
          :label="t('audit.col.module')"
          width="120"
        >
          <template #default="{ row }">{{ auditModuleLabel(row.module) }}</template>
        </el-table-column>
        <el-table-column prop="targetId" :label="t('audit.col.target_id')" min-width="100" show-overflow-tooltip />
        <el-table-column :label="t('audit.col.ip')" min-width="120" show-overflow-tooltip>
          <template #default="{ row }">{{ row.ipAddress ?? '—' }}</template>
        </el-table-column>
      </el-table>
    </div>
    <div class="pager">
      <el-pagination
        v-model:current-page="page"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next"
        background
        @current-change="onPageChange"
        @size-change="onSizeChange"
      />
    </div>
  </el-card>
</template>

<style scoped>
.filter-card { border-radius: 12px; margin-bottom: 16px; }
.data-card   { border-radius: 12px; }

.operator-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.35;
}

.operator-name {
  font-weight: 500;
  color: var(--el-text-color-primary);
}

.operator-role {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}
</style>
