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

const store = useOperationLogStore()

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

const actionColorMap = (action: string): string => {
  if (action.startsWith('auth.')) return 'purple'
  if (action.endsWith('.create')) return 'green'
  if (action.endsWith('.update')) return 'blue'
  if (action.endsWith('.delete')) return 'red'
  if (action.endsWith('.status_change')) return 'orange'
  return 'default'
}

const targetTypeLabels: Record<string, string> = {
  user: '用户',
  role: '角色',
  route_group: '路由组',
  product: '产品',
  order: '订单',
  refund: '退款',
}

const targetTypeOptions = Object.entries(targetTypeLabels).map(([value, label]) => ({
  label,
  value,
}))

const columns = [
  { title: '操作', key: 'action', width: 140, fixed: 'left' as const },
  { title: '对象', key: 'target', width: 120 },
  { title: '描述', dataIndex: 'description', ellipsis: true },
  { title: '操作人', key: 'user_id', width: 100 },
  { title: 'IP', dataIndex: 'ip', width: 120 },
  { title: '时间', key: 'created_at', width: 160 },
  { title: '详情', key: 'action_btn', 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)
}

function formatTarget(type: string, id: number): string {
  const label = targetTypeLabels[type] || type
  if (type === 'user') {
    const name = store.userMap.get(Number(id))
    return name ? `${label} ${name}` : `${label} #${id}`
  }
  if (type === 'role') {
    const name = store.roleMap.get(Number(id))
    return name ? `${label} ${name}` : `${label} #${id}`
  }
  if (type === 'route_group') {
    const name = store.routeGroupMap.get(Number(id))
    return name ? `${label} ${name}` : `${label} #${id}`
  }
  return `${label} #${id}`
}

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

  try {
    const data = await api.get<OperationLogDetail>(`/api/v1/logs/operations/${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-input
            v-model:value="store.filters.action"
            placeholder="如 user.create"
            allow-clear
            style="width: 150px"
          />
        </a-form-item>
        <a-form-item label="对象类型">
          <a-select
            v-model:value="store.filters.target_type"
            placeholder="全部类型"
            allow-clear
            style="width: 120px"
          >
            <a-select-option
              v-for="opt in targetTypeOptions"
              :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 === 'action'">
            <a-tag :color="actionColorMap(record.action)">
              {{ record.action }}
            </a-tag>
          </template>
          <template v-else-if="column.key === 'target'">
            {{ formatTarget(record.target_type, record.target_id) }}
          </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 === 'created_at'">
            {{ formatTime(record.created_at) }}
          </template>
          <template v-else-if="column.key === 'action_btn'">
            <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="actionColorMap(detail.action)">
                {{ detail.action }}
              </a-tag>
            </a-descriptions-item>
            <a-descriptions-item label="对象">
              {{ formatTarget(detail.target_type, detail.target_id) }}
            </a-descriptions-item>
            <a-descriptions-item label="描述" :span="2">
              {{ detail.description }}
            </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="时间" :span="2">
              {{ formatTime(detail.created_at) }}
            </a-descriptions-item>
          </a-descriptions>

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