<template>
  <div class="logs-page">
    <!-- 统计卡片 -->
    <a-row :gutter="16" class="mb-4">
      <a-col :span="6">
        <a-card>
          <a-statistic
            title="日志总数"
            :value="statistics.totalCount"
            :loading="statsLoading"
          >
            <template #prefix>
              <FileTextOutlined />
            </template>
          </a-statistic>
        </a-card>
      </a-col>
      <a-col :span="6">
        <a-card>
          <a-statistic
            :title="`近${statistics.days}天日志`"
            :value="statistics.recentCount"
            :loading="statsLoading"
          >
            <template #prefix>
              <ClockCircleOutlined />
            </template>
          </a-statistic>
        </a-card>
      </a-col>
      <a-col :span="6">
        <a-card>
          <a-statistic
            title="操作类型数"
            :value="statistics.actionStats.length"
            :loading="statsLoading"
          >
            <template #prefix>
              <TagOutlined />
            </template>
          </a-statistic>
        </a-card>
      </a-col>
      <a-col :span="6">
        <a-card>
          <a-statistic
            title="今日日志"
            :value="todayCount"
            :loading="statsLoading"
          >
            <template #prefix>
              <CalendarOutlined />
            </template>
          </a-statistic>
        </a-card>
      </a-col>
    </a-row>

    <!-- 搜索区域 -->
    <a-card class="mb-4">
      <a-form layout="inline" :model="searchForm" class="search-form">
        <a-form-item label="关键字">
          <a-input
            v-model:value="searchForm.keyword"
            placeholder="搜索操作/内容"
            allow-clear
            style="width: 200px"
            @press-enter="handleSearch"
          />
        </a-form-item>
        <a-form-item label="操作类型">
          <a-input
            v-model:value="searchForm.action"
            placeholder="如: GET /api/users"
            allow-clear
            style="width: 200px"
            @press-enter="handleSearch"
          />
        </a-form-item>
        <a-form-item label="IP地址">
          <a-input
            v-model:value="searchForm.ip"
            placeholder="搜索IP"
            allow-clear
            style="width: 150px"
            @press-enter="handleSearch"
          />
        </a-form-item>
        <a-form-item label="时间范围">
          <a-range-picker
            v-model:value="dateRange"
            :placeholder="['开始时间', '结束时间']"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            style="width: 240px"
          />
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button type="primary" @click="handleSearch">
              <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>

    <!-- 操作栏和表格 -->
    <a-card>
      <template #title>日志列表</template>
      <template #extra>
        <a-space>
          <a-button
            v-permission="'log:delete'"
            :disabled="selectedRowKeys.length === 0"
            danger
            @click="handleBatchDelete"
          >
            <template #icon><DeleteOutlined /></template>
            批量删除 {{ selectedRowKeys.length > 0 ? `(${selectedRowKeys.length})` : '' }}
          </a-button>
          <a-button
            v-permission="'log:delete'"
            type="primary"
            danger
            ghost
            @click="handleCleanOldLogs"
          >
            <template #icon><ClearOutlined /></template>
            清理过期日志
          </a-button>
        </a-space>
      </template>

      <a-table
        :columns="columns"
        :data-source="dataSource"
        :loading="loading"
        :pagination="pagination"
        :row-selection="{ selectedRowKeys, onChange: onSelectChange }"
        :row-key="(record) => record.id"
        @change="handleTableChange"
        :scroll="{ x: 1200 }"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'user'">
            <span v-if="record.user">
              {{ record.user.nickname || record.user.username }}
            </span>
            <span v-else class="text-gray-400">-</span>
          </template>
          <template v-if="column.key === 'action'">
            <a-tag :color="getActionColor(record.action)">
              {{ record.action }}
            </a-tag>
          </template>
          <template v-if="column.key === 'content'">
            <a-typography-paragraph
              :ellipsis="{ rows: 1, expandable: false }"
              :content="record.content || '-'"
              style="margin: 0; max-width: 300px"
            />
          </template>
          <template v-if="column.key === 'ip'">
            <span>{{ record.ip || '-' }}</span>
          </template>
          <template v-if="column.key === 'createTime'">
            <span>{{ formatDate(record.createTime) }}</span>
          </template>
          <template v-if="column.key === 'operations'">
            <a-button type="link" size="small" @click="handleViewDetail(record)">
              详情
            </a-button>
          </template>
        </template>
      </a-table>
    </a-card>

    <!-- 日志详情弹窗 -->
    <a-modal
      v-model:open="detailModalVisible"
      title="日志详情"
      :footer="null"
      width="700px"
    >
      <a-descriptions :column="2" bordered v-if="currentLog">
        <a-descriptions-item label="日志ID">{{ currentLog.id }}</a-descriptions-item>
        <a-descriptions-item label="操作时间">{{ formatDate(currentLog.createTime) }}</a-descriptions-item>
        <a-descriptions-item label="操作用户">
          {{ currentLog.user?.nickname || currentLog.user?.username || '-' }}
        </a-descriptions-item>
        <a-descriptions-item label="用户ID">{{ currentLog.userId || '-' }}</a-descriptions-item>
        <a-descriptions-item label="操作类型" :span="2">
          <a-tag :color="getActionColor(currentLog.action)">{{ currentLog.action }}</a-tag>
        </a-descriptions-item>
        <a-descriptions-item label="IP地址">{{ currentLog.ip || '-' }}</a-descriptions-item>
        <a-descriptions-item label="User-Agent" :span="2">
          <a-typography-paragraph
            :ellipsis="{ rows: 2, expandable: true }"
            :content="currentLog.userAgent || '-'"
            style="margin: 0"
          />
        </a-descriptions-item>
        <a-descriptions-item label="操作内容" :span="2">
          <div class="log-content-wrapper">
            <pre class="log-content">{{ formatContent(currentLog.content) }}</pre>
          </div>
        </a-descriptions-item>
      </a-descriptions>
    </a-modal>

    <!-- 清理过期日志弹窗 -->
    <a-modal
      v-model:open="cleanModalVisible"
      title="清理过期日志"
      :confirm-loading="cleanLoading"
      @ok="handleConfirmClean"
    >
      <a-form :label-col="{ span: 8 }" :wrapper-col="{ span: 14 }">
        <a-form-item label="保留天数">
          <a-input-number
            v-model:value="cleanDays"
            :min="7"
            :max="365"
            style="width: 150px"
          />
          <span class="ml-2">天</span>
        </a-form-item>
        <a-form-item :wrapper-col="{ offset: 8 }">
          <a-alert
            type="warning"
            :message="`将删除 ${cleanDays} 天前的所有日志，此操作不可恢复！`"
            show-icon
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import type { TableColumnsType } from 'ant-design-vue'
import type { Dayjs } from 'dayjs'
import {
  FileTextOutlined,
  ClockCircleOutlined,
  TagOutlined,
  CalendarOutlined,
  SearchOutlined,
  ReloadOutlined,
  DeleteOutlined,
  ClearOutlined,
} from '@ant-design/icons-vue'
import {
  logsApi,
  type Log,
  type LogQueryParams,
  type LogStatistics,
} from '@/api/logs'
import { useListRequest } from '@/composables/useListRequest'

// 统计数据
const statsLoading = ref(false)
const statistics = ref<LogStatistics>({
  totalCount: 0,
  recentCount: 0,
  days: 7,
  actionStats: [],
  dailyStats: [],
})

// 计算今日日志数
const todayCount = computed(() => {
  const today = new Date().toISOString().split('T')[0]
  const todayStat = statistics.value.dailyStats.find((s) => {
    const dateStr = typeof s.date === 'string' ? s.date.split('T')[0] : new Date(s.date).toISOString().split('T')[0]
    return dateStr === today
  })
  return todayStat?.count || 0
})

// 搜索表单
const searchForm = reactive<LogQueryParams>({
  keyword: '',
  action: '',
  ip: '',
})
const dateRange = ref<[Dayjs | string, Dayjs | string] | null>(null)

// 选中行
const selectedRowKeys = ref<number[]>([])

// 详情弹窗
const detailModalVisible = ref(false)
const currentLog = ref<Log | null>(null)

// 清理弹窗
const cleanModalVisible = ref(false)
const cleanLoading = ref(false)
const cleanDays = ref(90)

// 使用列表请求组合函数
const {
  loading,
  dataSource,
  pagination,
  handleTableChange,
  refresh: refreshList,
  search,
  resetSearch,
} = useListRequest<Log>({
  requestFn: (params) => logsApi.getList(params),
  errorMessage: '获取日志列表失败',
  defaultPageSize: 20,
})

// 表格列定义
const columns: TableColumnsType = [
  { title: 'ID', dataIndex: 'id', key: 'id', width: 80 },
  { title: '操作用户', dataIndex: 'user', key: 'user', width: 120 },
  { title: '操作类型', dataIndex: 'action', key: 'action', width: 200 },
  { title: '操作内容', dataIndex: 'content', key: 'content', ellipsis: true },
  { title: 'IP地址', dataIndex: 'ip', key: 'ip', width: 130 },
  { title: '操作时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
  { title: '操作', key: 'operations', width: 80, fixed: 'right' },
]

// 格式化日期
const formatDate = (dateStr?: string) => {
  if (!dateStr) return '-'
  const date = new Date(dateStr)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  })
}

// 格式化内容
const formatContent = (content?: string) => {
  if (!content) return '-'
  try {
    const parsed = JSON.parse(content)
    return JSON.stringify(parsed, null, 2)
  } catch {
    return content
  }
}

// 根据操作类型返回颜色
const getActionColor = (action: string) => {
  if (action.startsWith('GET')) return 'blue'
  if (action.startsWith('POST')) return 'green'
  if (action.startsWith('PUT') || action.startsWith('PATCH')) return 'orange'
  if (action.startsWith('DELETE')) return 'red'
  return 'default'
}

// 加载统计数据
const fetchStatistics = async () => {
  statsLoading.value = true
  try {
    statistics.value = await logsApi.getStatistics(7)
  } catch (error) {
    console.error('获取日志统计失败:', error)
  } finally {
    statsLoading.value = false
  }
}

// 搜索
const handleSearch = () => {
  const params: LogQueryParams = { ...searchForm }
  if (dateRange.value && dateRange.value[0] && dateRange.value[1]) {
    params.startTime = typeof dateRange.value[0] === 'string' ? dateRange.value[0] : dateRange.value[0].format('YYYY-MM-DD')
    params.endTime = typeof dateRange.value[1] === 'string' ? dateRange.value[1] : dateRange.value[1].format('YYYY-MM-DD')
  }
  search(params)
}

// 重置
const handleReset = () => {
  searchForm.keyword = ''
  searchForm.action = ''
  searchForm.ip = ''
  dateRange.value = null
  resetSearch()
}

// 选择行变化
const onSelectChange = (keys: number[]) => {
  selectedRowKeys.value = keys
}

// 查看详情
const handleViewDetail = (record: Log) => {
  currentLog.value = record
  detailModalVisible.value = true
}

// 批量删除
const handleBatchDelete = () => {
  if (selectedRowKeys.value.length === 0) {
    message.warning('请选择要删除的日志')
    return
  }

  Modal.confirm({
    title: '确认删除',
    content: `确定要删除选中的 ${selectedRowKeys.value.length} 条日志吗？此操作不可恢复。`,
    okText: '确定',
    okType: 'danger',
    cancelText: '取消',
    onOk: async () => {
      try {
        await logsApi.delete(selectedRowKeys.value)
        message.success('删除成功')
        selectedRowKeys.value = []
        refreshList()
        fetchStatistics()
      } catch (error: any) {
        message.error(error?.response?.data?.message || '删除失败')
      }
    },
  })
}

// 清理过期日志
const handleCleanOldLogs = () => {
  cleanDays.value = 90
  cleanModalVisible.value = true
}

// 确认清理
const handleConfirmClean = async () => {
  cleanLoading.value = true
  try {
    const result = await logsApi.clean(cleanDays.value)
    message.success(`成功清理 ${result.deleted} 条过期日志`)
    cleanModalVisible.value = false
    refreshList()
    fetchStatistics()
  } catch (error: any) {
    message.error(error?.response?.data?.message || '清理失败')
  } finally {
    cleanLoading.value = false
  }
}

// 初始化
onMounted(() => {
  fetchStatistics()
})
</script>

<style scoped>
.logs-page {
  padding: 0;
}

.search-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.log-content-wrapper {
  max-height: 300px;
  overflow: auto;
  background: #f5f5f5;
  border-radius: 4px;
  padding: 8px;
}

.log-content {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-all;
  font-size: 12px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
}

.text-gray-400 {
  color: #9ca3af;
}

.mb-4 {
  margin-bottom: 16px;
}

.ml-2 {
  margin-left: 8px;
}
</style>
