<template>
  <div class="page">
    <PageHeader
      :title="t('logs.title')"
      :description="t('logs.description')"
    >
      <template #actions>
        <el-button @click="load">{{ t('common.refresh') }}</el-button>
      </template>
    </PageHeader>

    <AppCard>
      <div class="card-toolbar">
        <el-select
          v-model="filter.ingress_key_id"
          :placeholder="t('logs.ingress')"
          clearable
          filterable
          class="toolbar-select--country"
          @change="onFilterChange"
        >
          <el-option
            v-for="k in ingressKeys"
            :key="k.id"
            :label="k.name"
            :value="String(k.id)"
          />
        </el-select>
        <el-select
          v-model="filter.status"
          :placeholder="t('common.status')"
          clearable
          class="toolbar-select"
          @change="onFilterChange"
        >
          <el-option :label="t('logs.statusSuccess')" value="success" />
          <el-option :label="t('logs.statusError')" value="error" />
        </el-select>
        <el-select
          v-model="filter.endpoint"
          :placeholder="t('logs.endpoint')"
          clearable
          class="toolbar-select--country"
          @change="onFilterChange"
        >
          <el-option :label="t('logs.endpointAdminLogin')" value="admin_login" />
          <el-option label="chat/completions" value="chat_completion" />
          <el-option label="embeddings" value="embeddings" />
          <el-option label="rerank" value="rerank" />
          <el-option label="prediction" value="prediction" />
        </el-select>
        <el-input
          v-model="filter.model"
          :placeholder="t('logs.modelOrUserPlaceholder')"
          clearable
          class="toolbar-input"
          @keyup.enter="onFilterChange"
          @clear="onFilterChange"
        />
        <el-input
          v-model="filter.client_ip"
          :placeholder="t('logs.clientIpPlaceholder')"
          clearable
          class="toolbar-select--country"
          @keyup.enter="onFilterChange"
          @clear="onFilterChange"
        />
        <el-button type="primary" @click="onFilterChange">{{ t('common.query') }}</el-button>
      </div>

      <el-table :data="logs" v-loading="loading" size="small">
        <el-table-column prop="created_at" :label="t('common.time')" width="170">
          <template #default="{ row }">{{ formatDateTime(row.created_at) }}</template>
        </el-table-column>
        <el-table-column prop="ingress_name" :label="t('logs.ingress')" width="120" show-overflow-tooltip>
          <template #default="{ row }">{{ row.ingress_name || t('common.dash') }}</template>
        </el-table-column>
        <el-table-column prop="endpoint" :label="t('logs.endpoint')" width="130">
          <template #default="{ row }">{{ endpointLabel(row.endpoint) }}</template>
        </el-table-column>
        <el-table-column prop="client_ip" :label="t('dashboard.clientIp')" width="130" show-overflow-tooltip />
        <el-table-column prop="model" :label="t('logs.modelOrUser')" min-width="140" show-overflow-tooltip>
          <template #default="{ row }">{{ row.model || t('common.dash') }}</template>
        </el-table-column>
        <el-table-column prop="latency_ms" :label="t('common.latencyMs')" width="100">
          <template #default="{ row }">{{ row.endpoint === 'admin_login' ? t('common.dash') : row.latency_ms }}</template>
        </el-table-column>
        <el-table-column prop="stream" :label="t('common.stream')" width="70">
          <template #default="{ row }">{{ row.endpoint === 'admin_login' ? t('common.dash') : (row.stream ? t('common.yes') : t('common.no')) }}</template>
        </el-table-column>
        <el-table-column prop="status" :label="t('common.status')" width="80">
          <template #default="{ row }">
            <el-tag :type="row.status === 'success' ? 'success' : 'danger'" size="small">
              {{ row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="error_msg" :label="t('common.error')" min-width="120" show-overflow-tooltip />
        <el-table-column :label="t('common.actions')" width="80" fixed="right">
          <template #default="{ row }">
            <el-button link type="primary" size="small" @click="openDetail(row.id)">{{ t('common.detail') }}</el-button>
          </template>
        </el-table-column>
      </el-table>

      <p class="card-footer-hint">{{ t('logs.pagerHint', { total, max: maxKept }) }}</p>
      <div class="card-pager">
        <el-pagination
          v-model:current-page="page"
          v-model:page-size="pageSize"
          :total="total"
          :page-sizes="[10, 20, 50]"
          layout="total, sizes, prev, pager, next"
          background
          small
          @current-change="load"
          @size-change="onSizeChange"
        />
      </div>
    </AppCard>

    <el-drawer v-model="detailVisible" :title="t('logs.detailTitle')" size="50%">
      <p v-if="detailLoading" class="form-hint text-center u-mb-4">{{ t('common.loading') }}</p>
      <template v-else-if="detail">
        <div class="kv-block u-mb-4">
          <p><span class="label">{{ t('common.time') }}</span> {{ formatDateTime(detail.created_at) }}</p>
          <p><span class="label">{{ t('logs.ingress') }}</span> {{ detail.ingress_name || t('common.dash') }}</p>
          <p><span class="label">{{ t('logs.endpoint') }}</span> {{ endpointLabel(detail.endpoint) }}</p>
          <p><span class="label">{{ detail.endpoint === 'admin_login' ? t('common.username') : t('common.model') }}</span> {{ detail.model || t('common.dash') }}</p>
          <p><span class="label">{{ t('dashboard.clientIp') }}</span> {{ detail.client_ip || t('common.dash') }}</p>
          <p v-if="detail.endpoint !== 'admin_login'"><span class="label">{{ t('common.latency') }}</span> {{ detail.latency_ms }} ms</p>
          <p><span class="label">{{ t('common.status') }}</span>
            <el-tag :type="detail.status === 'success' ? 'success' : 'danger'" size="small">
              {{ detail.status }}
            </el-tag>
          </p>
          <p v-if="detail.error_msg"><span class="label">{{ t('common.error') }}</span> <span class="status-bad">{{ detail.error_msg }}</span></p>
        </div>
        <div v-if="predictionDetail" class="u-mb-4">
          <div class="section-title">{{ t('logs.predictionStatus') }}</div>
          <p><el-tag size="small">{{ predictionDetail.status }}</el-tag></p>
          <div v-if="predictionImages.length" class="image-grid u-mt-2">
            <a v-for="img in predictionImages" :key="img.id" :href="`/api/admin/images/${img.id}`" target="_blank">
              <img :src="`/api/admin/images/${img.id}`" class="thumb" :alt="img.filename" />
            </a>
          </div>
        </div>
        <div class="section-title">{{ t('logs.requestBody') }}</div>
        <pre class="card-inset-block u-mb-4">{{ formatBody(detail.request_body) }}</pre>
        <div class="section-title">{{ t('logs.responseBody') }}</div>
        <pre class="card-inset-block">{{ formatBody(detail.response_body) }}</pre>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import api from '@/api/client'
import PageHeader from '@/components/PageHeader.vue'
import AppCard from '@/components/AppCard.vue'
import { formatDateTime } from '@/utils/format'

const { t } = useI18n()

interface RequestLog {
  id: number
  ingress_key_id: number
  ingress_name: string
  endpoint: string
  client_ip: string
  model: string
  latency_ms: number
  status: string
  stream: boolean
  error_msg: string
  created_at: string
}

interface RequestLogDetail extends RequestLog {
  request_body: string
  response_body: string
}

interface IngressKey {
  id: number
  name: string
}

const logs = ref<RequestLog[]>([])
const ingressKeys = ref<IngressKey[]>([])
const loading = ref(false)
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)
const maxKept = ref(500)
const filter = ref({
  ingress_key_id: '',
  status: '',
  endpoint: '',
  model: '',
  client_ip: '',
})

const detailVisible = ref(false)
const detailLoading = ref(false)
const detail = ref<RequestLogDetail | null>(null)
const predictionDetail = ref<{ status: string } | null>(null)
const predictionImages = ref<{ id: string; filename: string }[]>([])

function endpointLabel(endpoint: string) {
  if (endpoint === 'admin_login') return t('logs.endpointAdminLogin')
  if (endpoint === 'prediction') return 'prediction'
  const labels: Record<string, string> = {
    chat_completion: 'chat/completions',
    embeddings: 'embeddings',
    rerank: 'rerank',
    responses: 'responses',
  }
  return labels[endpoint] || endpoint
}

function formatBody(raw: string) {
  if (!raw) return t('common.empty')
  try {
    return JSON.stringify(JSON.parse(raw), null, 2)
  } catch {
    return raw
  }
}

function buildParams(): Record<string, string> {
  const params: Record<string, string> = {
    page: String(page.value),
    page_size: String(pageSize.value),
  }
  const f = filter.value
  if (f.ingress_key_id) params.ingress_key_id = f.ingress_key_id
  if (f.status) params.status = f.status
  if (f.endpoint) params.endpoint = f.endpoint
  if (f.model) params.model = f.model
  if (f.client_ip) params.client_ip = f.client_ip
  return params
}

async function loadIngressKeys() {
  const res = await api.get('/ingress-keys')
  ingressKeys.value = res.data.data
}

async function load() {
  loading.value = true
  try {
    const res = await api.get('/request-logs', { params: buildParams() })
    logs.value = res.data.data
    total.value = res.data.total
    maxKept.value = res.data.max_kept ?? 500
  } finally {
    loading.value = false
  }
}

function onFilterChange() {
  page.value = 1
  load()
}

function onSizeChange() {
  page.value = 1
  load()
}

async function openDetail(id: number) {
  detailVisible.value = true
  detailLoading.value = true
  detail.value = null
  predictionDetail.value = null
  predictionImages.value = []
  try {
    const res = await api.get(`/request-logs/${id}`)
    detail.value = res.data.data
    if (detail.value?.endpoint === 'prediction' && detail.value.model) {
      try {
        const pred = await api.get(`/predictions/${detail.value.model}`)
        predictionDetail.value = pred.data.prediction
        predictionImages.value = pred.data.images || []
      } catch { /* ignore */ }
    }
  } finally {
    detailLoading.value = false
  }
}

onMounted(async () => {
  await loadIngressKeys()
  await load()
})
</script>
