<script setup lang="ts">
import dayjs from 'dayjs'
import { api } from '@/utils/request'
import { useRequestLogStore } from '@/stores/request-log'
import type { RequestLogDetail } from '@/types/api'
import {
  SearchOutlined,
  ReloadOutlined,
  EyeOutlined,
} from '@ant-design/icons-vue'

const store = useRequestLogStore()

// Detail drawer
const drawerVisible = ref(false)
const drawerLoading = ref(false)
const detail = ref<RequestLogDetail | null>(null)
let detailRequestId = 0

const methodColorMap: Record<string, string> = {
  GET: 'green',
  POST: 'blue',
  PUT: 'orange',
  DELETE: 'red',
  PATCH: 'cyan',
}

const statusCodeColor = (code: number) => {
  if (code >= 200 && code < 300) return 'green'
  if (code >= 400 && code < 500) return 'orange'
  if (code >= 500) return 'red'
  return 'default'
}

const durationClass = (ms: number) => {
  if (ms > 3000) return 'text-red-500 font-semibold'
  if (ms > 1000) return 'text-yellow-600 font-semibold'
  return ''
}

const methodOptions = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'].map((m) => ({
  label: m,
  value: m,
}))

const statusCodeOptions = [200, 201, 400, 401, 403, 404, 500].map((c) => ({
  label: String(c),
  value: c,
}))

const columns = [
  { title: '方法', key: 'method', width: 80, fixed: 'left' as const },
  { title: '路径', dataIndex: 'path', ellipsis: true },
  { title: '状态码', key: 'status_code', width: 80 },
  { title: '用户', key: 'user_id', width: 100 },
  { title: '耗时', key: 'duration_ms', width: 80 },
  { title: 'IP', dataIndex: 'ip', width: 120 },
  { title: '时间', key: 'created_at', width: 160 },
  { title: '操作', key: 'action', width: 80, fixed: 'right' as const },
]

// RangePicker dayjs 桥接
const createdAtRange = computed({
  get: () => {
    if (!store.filters.created_at_range) return undefined
    return store.filters.created_at_range.map((d) => dayjs(d)) as [dayjs.Dayjs, dayjs.Dayjs]
  },
  set: (val) => {
    store.filters.created_at_range = val
      ? [val[0].format('YYYY-MM-DD'), val[1].format('YYYY-MM-DD')]
      : null
  },
})

onMounted(async () => {
  await store.loadLookups()
  store.fetchLogs()
})

function handleSearch() {
  store.pagination.page = 1
  store.fetchLogs()
}

function handleReset() {
  store.resetFilters()
  store.fetchLogs()
}

function handlePageChange(page: number, pageSize: number) {
  store.pagination.page = page
  store.pagination.per_page = pageSize
  store.fetchLogs()
}

function formatTime(time: string | null) {
  if (!time) return '-'
  return time.replace('T', ' ').substring(0, 16)
}

async function handleViewDetail(record: { id: number }) {
  const currentRequestId = ++detailRequestId
  drawerVisible.value = true
  drawerLoading.value = true
  detail.value = null

  try {
    const data = await api.get<RequestLogDetail>(`/api/v1/logs/requests/${record.id}`)
    if (currentRequestId !== detailRequestId) return
    detail.value = data
  } catch {
    if (currentRequestId !== detailRequestId) return
    message.error('获取请求日志详情失败')
  } finally {
    if (currentRequestId === detailRequestId) {
      drawerLoading.value = false
    }
  }
}
</script>

<template>
  <div>
    <h2 class="text-xl font-semibold mb-4">请求日志</h2>

    <!-- Filter area -->
    <a-card class="mb-4">
      <a-form layout="inline" @submit.prevent="handleSearch">
        <a-form-item label="方法">
          <a-select
            v-model:value="store.filters.method"
            placeholder="全部方法"
            allow-clear
            style="width: 110px"
          >
            <a-select-option v-for="opt in methodOptions" :key="opt.value" :value="opt.value">
              {{ opt.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="路径">
          <a-input
            v-model:value="store.filters.path"
            placeholder="模糊搜索"
            allow-clear
            style="width: 180px"
          />
        </a-form-item>
        <a-form-item label="状态码">
          <a-select
            v-model:value="store.filters.status_code"
            placeholder="全部"
            allow-clear
            style="width: 100px"
          >
            <a-select-option
              v-for="opt in statusCodeOptions"
              :key="opt.value"
              :value="opt.value"
            >
              {{ opt.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="用户">
          <a-select
            v-model:value="store.filters.user_id"
            placeholder="全部用户"
            allow-clear
            style="width: 140px"
          >
            <a-select-option v-for="u in store.users" :key="u.id" :value="u.id">
              {{ u.username }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="时间范围">
          <a-range-picker v-model:value="createdAtRange" format="YYYY-MM-DD" />
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button type="primary" html-type="submit">
              <template #icon><SearchOutlined /></template>
              搜索
            </a-button>
            <a-button @click="handleReset">
              <template #icon><ReloadOutlined /></template>
              重置
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-card>

    <!-- Table -->
    <a-card>
      <a-table
        :columns="columns"
        :data-source="store.logs"
        :loading="store.loading"
        :pagination="false"
        :scroll="{ x: 900 }"
        row-key="id"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'method'">
            <a-tag :color="methodColorMap[record.method] || 'default'">
              {{ record.method }}
            </a-tag>
          </template>
          <template v-else-if="column.key === 'status_code'">
            <a-tag :color="statusCodeColor(record.status_code)">
              {{ record.status_code }}
            </a-tag>
          </template>
          <template v-else-if="column.key === 'user_id'">
            {{ record.user_id ? (store.userMap.get(Number(record.user_id)) || `#${record.user_id}`) : '-' }}
          </template>
          <template v-else-if="column.key === 'duration_ms'">
            <span :class="durationClass(record.duration_ms)">
              {{ record.duration_ms }}ms
            </span>
          </template>
          <template v-else-if="column.key === 'created_at'">
            {{ formatTime(record.created_at) }}
          </template>
          <template v-else-if="column.key === 'action'">
            <a-button
              type="link"
              size="small"
              @click="handleViewDetail(record as { id: number })"
            >
              <template #icon><EyeOutlined /></template>
              查看
            </a-button>
          </template>
        </template>
      </a-table>

      <div class="mt-4 flex justify-end">
        <a-pagination
          :current="store.pagination.page"
          :page-size="store.pagination.per_page"
          :total="store.pagination.total"
          show-size-changer
          show-quick-jumper
          :show-total="(total: number) => `共 ${total} 条`"
          @change="handlePageChange"
        />
      </div>
    </a-card>

    <!-- Detail drawer -->
    <a-drawer
      title="请求日志详情"
      :open="drawerVisible"
      :width="720"
      @close="drawerVisible = false"
    >
      <a-spin :spinning="drawerLoading">
        <template v-if="detail">
          <a-descriptions title="请求信息" :column="2" bordered class="mb-4">
            <a-descriptions-item label="方法">
              <a-tag :color="methodColorMap[detail.method] || 'default'">
                {{ detail.method }}
              </a-tag>
            </a-descriptions-item>
            <a-descriptions-item label="状态码">
              <a-tag :color="statusCodeColor(detail.status_code)">
                {{ detail.status_code }}
              </a-tag>
            </a-descriptions-item>
            <a-descriptions-item label="路径" :span="2">{{ detail.path }}</a-descriptions-item>
            <a-descriptions-item label="用户">
              {{
                detail.user_id
                  ? (store.userMap.get(Number(detail.user_id)) || `#${detail.user_id}`)
                  : '-'
              }}
            </a-descriptions-item>
            <a-descriptions-item label="IP">{{ detail.ip }}</a-descriptions-item>
            <a-descriptions-item label="响应码">{{ detail.response_code }}</a-descriptions-item>
            <a-descriptions-item label="耗时">
              <span :class="durationClass(detail.duration_ms)">
                {{ detail.duration_ms }}ms
              </span>
            </a-descriptions-item>
            <a-descriptions-item label="User-Agent" :span="2">
              {{ detail.user_agent || '-' }}
            </a-descriptions-item>
            <a-descriptions-item label="时间" :span="2">
              {{ formatTime(detail.created_at) }}
            </a-descriptions-item>
          </a-descriptions>

          <h3 class="text-base font-medium mb-2">请求体</h3>
          <pre
            v-if="detail.request_body"
            class="m-0 p-3 text-xs max-h-80 overflow-auto bg-gray-50 rounded border"
          >{{ JSON.stringify(detail.request_body, null, 2) }}</pre>
          <p v-else class="text-gray-400">无请求体数据</p>
        </template>
      </a-spin>
    </a-drawer>
  </div>
</template>
