<template>
  <div class="container">
    <search-table
      :form-model="formModel"
      :form-items="formItems"
      :data="tableData"
      :columns="tableColumns"
      :loading="loading"
      :pagination="pagination"
      :title="pageTitle"
      @update:form-model="handleFormModelUpdate"
      @search="handleSearch"
      @reset="handleReset"
      @refresh="handleRefresh"
      @page-change="handlePageChange"
      @page-size-change="handlePageSizeChange"
    >
      <template #form-items>
        <a-col :span="8">
          <a-form-item label="创建时间" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }">
            <a-range-picker
              v-model="formModel.timeRange"
              show-time
              format="YYYY-MM-DD HH:mm:ss"
              value-format="YYYY-MM-DD HH:mm:ss"
              style="width: 100%"
            />
          </a-form-item>
        </a-col>
      </template>

      <template #reportType="{ record }">
        {{ reportTypeLabel[record.report_type] || record.report_type || '—' }}
      </template>

      <template #status="{ record }">
        <a-tag :color="reportStatusColor(record.status)">
          {{ reportStatusLabel[record.status] || record.status || '—' }}
        </a-tag>
      </template>

      <template #failureReason="{ record }">
        {{ record.error_message || '—' }}
      </template>

      <template #operations="{ record }">
        <a-button
          v-if="canDownloadPDF(record)"
          type="text"
          size="small"
          :loading="downloadingIds.has(record.id)"
          @click="handleDownloadPDF(record)"
        >
          下载 PDF
        </a-button>
        <span v-else-if="record.status === 'failed'" class="operation-note">生成失败</span>
        <span v-else-if="record.status === 'pending' || record.status === 'running'" class="operation-note">生成中</span>
        <span v-else class="operation-note">无 PDF</span>
      </template>
    </search-table>
  </div>
</template>

<script lang="ts" setup>
import { computed, onBeforeUnmount, reactive, ref } from 'vue'
import { Message } from '@arco-design/web-vue'
import SearchTable from '@/components/search-table/index.vue'
import type { FormItem } from '@/components/search-form/types'
import { fetchReportList, ReportStatus, ReportType, type ReportListParams, type ReportRecord } from '@/api/ops/report'
import { downloadReportFile } from '../useReportExport'
import { normalizeReportRows, reportStatusColor, reportStatusLabel } from '../useReportListRow'

const pageTitle = '历史报告'

const reportTypeLabel: Record<string, string> = {
  topn: 'TopN报表',
  statistics: '统计报告',
  traffic: '流量统计报告',
  fault: '故障报告',
  server: '服务器报告',
  network_device: '网络设备报告',
  operations: '综合运维报告',
  evidence: '证据导出',
}

const pdfReportTypes = new Set([
  ReportType.TOPN,
  ReportType.STATISTICS,
  ReportType.TRAFFIC,
  ReportType.FAULT,
  ReportType.SERVER,
  ReportType.NETWORK_DEVICE,
  ReportType.OPERATIONS,
])

const formModel = ref<{
  report_type: ReportType | ''
  status: ReportStatus | ''
  keyword: string
  timeRange?: string[]
}>({
  report_type: '',
  status: '',
  keyword: '',
  timeRange: [],
})

const formItems = computed<FormItem[]>(() => [
  {
    field: 'report_type',
    label: '报表类型',
    type: 'select',
    span: 8,
    placeholder: '请选择',
    options: [
      { value: '', label: '全部' },
      { value: ReportType.TOPN, label: reportTypeLabel.topn },
      { value: ReportType.STATISTICS, label: reportTypeLabel.statistics },
      { value: ReportType.TRAFFIC, label: reportTypeLabel.traffic },
      { value: ReportType.FAULT, label: reportTypeLabel.fault },
      { value: ReportType.SERVER, label: reportTypeLabel.server },
      { value: ReportType.NETWORK_DEVICE, label: reportTypeLabel.network_device },
      { value: ReportType.OPERATIONS, label: reportTypeLabel.operations },
    ],
  },
  {
    field: 'status',
    label: '状态',
    type: 'select',
    span: 8,
    placeholder: '请选择',
    options: [
      { value: '', label: '全部' },
      { value: ReportStatus.PENDING, label: reportStatusLabel.pending },
      { value: ReportStatus.RUNNING, label: reportStatusLabel.running },
      { value: ReportStatus.SUCCESS, label: reportStatusLabel.success },
      { value: ReportStatus.FAILED, label: reportStatusLabel.failed },
    ],
  },
  {
    field: 'keyword',
    label: '标题',
    type: 'input',
    span: 8,
    placeholder: '请输入标题关键字',
  },
])

const loading = ref(false)
const downloadingIds = reactive(new Set<number>())
const tableData = ref<ReportRecord[]>([])
let latestRequestId = 0

onBeforeUnmount(() => {
  latestRequestId += 1
})

const pagination = reactive({
  current: 1,
  pageSize: 20,
  total: 0,
  showTotal: true,
  showJumper: true,
  showPageSize: true,
})

const tableColumns = computed(() => [
  {
    title: '报告编号',
    dataIndex: 'id',
    width: 100,
  },
  {
    title: '标题',
    dataIndex: 'title',
    width: 220,
  },
  {
    title: '报表类型',
    dataIndex: 'report_type',
    width: 150,
    slotName: 'reportType',
  },
  {
    title: '状态',
    dataIndex: 'status',
    width: 100,
    slotName: 'status',
  },
  {
    title: '创建时间',
    dataIndex: 'created_at',
    width: 180,
  },
  {
    title: '完成时间',
    dataIndex: 'finished_at',
    width: 180,
  },
  {
    title: '失败原因',
    dataIndex: 'error_message',
    width: 220,
    slotName: 'failureReason',
  },
  {
    title: '操作',
    dataIndex: 'operations',
    width: 120,
    slotName: 'operations',
    fixed: 'right' as const,
  },
])

const canDownloadPDF = (record: ReportRecord) =>
  record.status === ReportStatus.SUCCESS && pdfReportTypes.has(record.report_type as ReportType)

const fetchList = async (): Promise<boolean> => {
  const requestId = ++latestRequestId
  loading.value = true

  const reportType = formModel.value.report_type
  const status = formModel.value.status
  const keyword = formModel.value.keyword.trim()
  const timeRange = formModel.value.timeRange
  const page = pagination.current
  const size = pagination.pageSize
  const params: ReportListParams = {
    page,
    size,
  }

  if (reportType) {
    params.report_type = reportType
  }
  if (status) {
    params.status = status
  }
  if (keyword) {
    params.keyword = keyword
  }
  if (timeRange?.length === 2 && timeRange[0] && timeRange[1]) {
    params.created_from = timeRange[0]
    params.created_to = timeRange[1]
  }

  try {
    while (true) {
      const res = await fetchReportList(params)
      if (requestId !== latestRequestId) return false

      if (res.code !== 0 || !res.details) {
        tableData.value = []
        pagination.total = 0
        Message.error(res.message || '获取报表列表失败')
        return false
      }

      const total = res.details.total || 0
      const maximumPage = Math.max(1, Math.ceil(total / size))
      if ((params.page || 1) > maximumPage) {
        pagination.current = maximumPage
        params.page = maximumPage
        continue
      }

      tableData.value = normalizeReportRows(res.details.data || [])
      pagination.total = total
      return true
    }
  } catch (error: any) {
    if (requestId !== latestRequestId) return false

    tableData.value = []
    pagination.total = 0
    console.error('获取报表列表失败:', error)
    Message.error(error.message || '获取报表列表失败')
    return false
  } finally {
    if (requestId === latestRequestId) {
      loading.value = false
    }
  }
}

const handleFormModelUpdate = (value: Record<string, any>) => {
  formModel.value = {
    ...formModel.value,
    ...value,
  }
}

const handleSearch = () => {
  pagination.current = 1
  fetchList()
}

const handleReset = () => {
  formModel.value = {
    report_type: '',
    status: '',
    keyword: '',
    timeRange: [],
  }
  pagination.current = 1
  fetchList()
}

const handleRefresh = async () => {
  if (await fetchList()) {
    Message.success('数据已刷新')
  }
}

const handlePageChange = (current: number) => {
  pagination.current = current
  fetchList()
}

const handlePageSizeChange = (pageSize: number) => {
  pagination.pageSize = pageSize
  pagination.current = 1
  fetchList()
}

const handleDownloadPDF = async (record: ReportRecord) => {
  downloadingIds.add(record.id)
  try {
    await downloadReportFile(record, 'pdf')
    Message.success('PDF 下载成功')
  } catch (error: any) {
    console.error('PDF 下载失败:', error)
    Message.error(error.message || 'PDF 下载失败')
  } finally {
    downloadingIds.delete(record.id)
  }
}

fetchList()
</script>

<script lang="ts">
export default {
  name: 'ReportHistory',
}
</script>

<style scoped lang="less">
.container {
  padding: 20px;

  .operation-note {
    color: var(--color-text-3);
  }
}
</style>
