<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"
    >
      <!-- 自定义表单项：创建时间范围 -->
      <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 #toolbar-left>
        <a-space>
          <a-button type="primary" @click="handleOpenGenerateModal">
            <template #icon><icon-file-add /></template>
            生成报表
          </a-button>
        </a-space>
      </template>

      <!-- 工具栏右侧：查看和导出按钮 -->
      <template #toolbar-right>
        <a-space>
          <a-button v-if="selectedRecord" type="outline" @click="handleViewContent()">
            <template #icon><icon-eye /></template>
            查看内容
          </a-button>
          <a-dropdown v-if="selectedRecord">
            <a-button type="outline">
              <template #icon><icon-download /></template>
              导出
            </a-button>
            <template #content>
              <a-doption @click="handleExport('csv')">导出 CSV</a-doption>
              <a-doption @click="handleExport('xlsx')">导出 Excel</a-doption>
              <a-doption @click="handleExport('pdf')">导出 PDF</a-doption>
            </template>
          </a-dropdown>
        </a-space>
      </template>

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

      <!-- 操作列 -->
      <template #operations="{ record }">
        <a-space>
          <a-button v-if="record.status === 'success'" type="text" size="small" @click="handleViewContent(record)">查看</a-button>
          <a-button v-if="record.status === 'success'" type="text" size="small" @click="handleExport('csv', record)">CSV</a-button>
          <a-button v-if="record.status === 'success'" type="text" size="small" @click="handleExport('xlsx', record)">Excel</a-button>
          <a-button v-if="record.status === 'success'" type="text" size="small" @click="handleExport('pdf', record)">PDF</a-button>
        </a-space>
      </template>
    </search-table>

    <!-- 生成报表弹窗 -->
    <a-modal
      v-model:visible="generateModalVisible"
      title="生成 TopN 报表"
      :width="600"
      :ok-loading="generating"
      @ok="handleGenerate"
      @cancel="handleCloseGenerateModal"
    >
      <a-form :model="generateForm" layout="vertical">
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="数据源" field="data_source" :rules="[{ required: true, message: '请选择数据源' }]">
              <a-select v-model="generateForm.data_source" placeholder="请选择" style="width: 100%">
                <a-option value="dc-host">主机</a-option>
                <a-option value="dc-network">网络</a-option>
                <a-option value="dc-database">数据库</a-option>
                <a-option value="dc-middleware">中间件</a-option>
                <a-option value="alert">告警频率</a-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="指标" field="metric_id" :rules="[{ required: true, message: '请选择指标' }]">
              <a-select
                v-model="generateForm.metric_id"
                allow-clear
                allow-search
                :loading="metricOptionsLoading"
                :options="metricOptions"
                :placeholder="generateForm.data_source ? '请选择逻辑指标' : '请先选择数据源'"
                :disabled="!generateForm.data_source || generateForm.data_source === 'alert'"
                style="width: 100%"
              />
            </a-form-item>
          </a-col>
        </a-row>

        <a-form-item label="目标标识" field="target_identities" :rules="[{ required: true, message: '请选择目标标识' }]">
          <a-select
            v-model="generateForm.target_identities"
            multiple
            allow-clear
            allow-search
            :loading="targetOptionsLoading"
            :options="targetIdentityOptions"
            :placeholder="generateForm.data_source ? '请选择或搜索目标（可多选）' : '请先选择数据源'"
            :disabled="!generateForm.data_source || generateForm.data_source === 'alert'"
            :max-tag-count="3"
            style="width: 100%"
          />
          <div v-if="generateForm.data_source === 'alert'" class="target-id-hint">
            告警频率 TopN 按 dedupe_key/告警名聚合，无需选择目标标识。
          </div>
          <div v-if="generateForm.data_source === 'dc-network'" class="target-id-hint">
            TopN 当前实现可能对「网络」数据源无法出数；选项来自网络设备服务列表，供对齐标识使用。
          </div>
        </a-form-item>

        <a-form-item label="时间范围" field="timeRange" :rules="[{ required: true, message: '请选择时间范围' }]">
          <a-range-picker
            v-model="generateForm.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-row :gutter="16">
          <a-col :span="8">
            <a-form-item label="Top N" field="n">
              <a-input-number v-model="generateForm.n" placeholder="默认10" :min="1" :max="500" style="width: 100%" />
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="排名聚合" field="rank_aggregate">
              <a-select v-model="generateForm.rank_aggregate" placeholder="请选择" style="width: 100%">
                <a-option value="avg">平均值</a-option>
                <a-option value="max">最大值</a-option>
                <a-option value="min">最小值</a-option>
                <a-option value="last">最后值</a-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="排序" field="order">
              <a-select v-model="generateForm.order" placeholder="请选择" style="width: 100%">
                <a-option value="desc">降序</a-option>
                <a-option value="asc">升序</a-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>

        <a-form-item label="报表标题" field="title">
          <a-input v-model="generateForm.title" placeholder="可选，不填自动生成" style="width: 100%" />
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 查看内容弹窗 -->
    <a-modal v-model:visible="contentModalVisible" :title="contentModalTitle" :width="900" :footer="false">
      <div v-if="contentLoading" class="loading-container">
        <a-spin />
      </div>
      <div v-else-if="reportContent">
        <!-- 图表展示 -->
        <div ref="chartRef" class="chart-container"></div>

        <!-- 排名表格（引擎字段为 identity + value，见 dc-control genTopN） -->
        <a-table :data="normalizedRankingRows" :columns="rankingTableColumns" :pagination="false" stripe />
      </div>
      <a-empty v-else description="暂无数据" />
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, nextTick, watch } 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, generateReport, fetchReportContent, ReportType, type ReportRecord, type TopNReportParams } from '@/api/ops/report'
import * as echarts from 'echarts'
import { downloadReportFile } from '../useReportExport'
import type { ReportExportFormat } from '@/api/ops/report'
import { useReportTargetIdentityOptions } from '../useReportTargetIdentityOptions'
import { useReportMetricRegistryOptions } from '../useReportMetricRegistryOptions'
import { normalizeReportRows, reportStatusColor, reportStatusLabel } from '../useReportListRow'

const { targetIdentityOptions, targetOptionsLoading, loadTargetIdentityOptions } = useReportTargetIdentityOptions()

const { metricOptions, metricOptionsLoading, loadMetricRegistryOptions } = useReportMetricRegistryOptions()

// 页面标题
const pageTitle = 'TopN 报表'

// 列表筛选表单模型
const formModel = ref<{
  report_type: string
  status: string
  keyword: string
  timeRange: string[]
}>({
  report_type: ReportType.TOPN,
  status: '',
  keyword: '',
  timeRange: [],
})

// 表单项配置
const formItems = computed<FormItem[]>(() => [
  {
    field: 'status',
    label: '状态',
    type: 'select',
    span: 8,
    placeholder: '请选择',
    options: [
      { value: '', label: '全部' },
      { value: 'pending', label: '等待中' },
      { value: 'running', label: '生成中' },
      { value: 'success', label: '成功' },
      { value: 'failed', label: '失败' },
    ],
  },
  {
    field: 'keyword',
    label: '标题',
    type: 'input',
    span: 8,
    placeholder: '请输入标题关键字',
  },
])

// 状态
const loading = ref(false)
const generating = ref(false)
const contentLoading = ref(false)
const exporting = ref(false)
const tableData = ref<ReportRecord[]>([])
const selectedRecord = ref<ReportRecord | null>(null)

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

// 表格列配置
const tableColumns = computed(() => [
  {
    title: 'ID',
    dataIndex: 'id',
    width: 80,
  },
  {
    title: '标题',
    dataIndex: 'title',
    width: 200,
  },
  {
    title: '状态',
    dataIndex: 'status',
    width: 100,
    slotName: 'status',
  },
  {
    title: '创建时间',
    dataIndex: 'created_at',
    width: 180,
  },
  {
    title: '更新时间',
    dataIndex: 'updated_at',
    width: 180,
  },
  {
    title: '操作',
    dataIndex: 'operations',
    width: 180,
    slotName: 'operations',
    fixed: 'right' as const,
  },
])

// 生成报表弹窗
const generateModalVisible = ref(false)
const generateForm = ref<{
  data_source: string
  metric_id: string
  target_identities: string[]
  timeRange: string[]
  n: number
  rank_aggregate: string
  order: string
  title: string
}>({
  data_source: '',
  metric_id: '',
  target_identities: [],
  timeRange: [],
  n: 10,
  rank_aggregate: 'avg',
  order: 'desc',
  title: '',
})

watch(
  () => generateForm.value.data_source,
  (ds) => {
    generateForm.value.target_identities = []
    generateForm.value.metric_id = ''
    if (ds === 'alert') {
      generateForm.value.metric_id = 'alert_frequency'
      return
    }
    loadTargetIdentityOptions(ds)
    loadMetricRegistryOptions(ds)
  }
)

// 查看内容弹窗
const contentModalVisible = ref(false)
const contentModalTitle = ref('')
const reportContent = ref<Record<string, any> | null>(null)
const chartRef = ref<HTMLElement | null>(null)
let chartInstance: echarts.ECharts | null = null

// 将引擎 ranking 规范为表格行：rank、target（展示用）、value
const normalizedRankingRows = computed(() => {
  const raw = reportContent.value?.ranking
  if (!Array.isArray(raw)) return []
  return raw.map((item: any, idx: number) => ({
    ...item,
    rank: item.rank ?? idx + 1,
    target: item.target ?? item.identity ?? item.target_identity ?? '',
    value: item.value,
  }))
})

// 排名表格列配置
const rankingTableColumns = computed(() => [
  {
    title: '排名',
    dataIndex: 'rank',
    width: 80,
  },
  {
    title: '目标',
    dataIndex: 'target',
    width: 200,
  },
  {
    title: '值',
    dataIndex: 'value',
    width: 150,
  },
])

// 获取报表列表
const fetchList = async () => {
  loading.value = true

  try {
    const params: any = {
      page: pagination.current,
      size: pagination.pageSize,
      report_type: ReportType.TOPN,
    }

    if (formModel.value.status) {
      params.status = formModel.value.status
    }

    if (formModel.value.keyword) {
      params.keyword = formModel.value.keyword
    }

    if (formModel.value.timeRange && formModel.value.timeRange.length === 2) {
      params.created_from = formModel.value.timeRange[0]
      params.created_to = formModel.value.timeRange[1]
    }

    const res = await fetchReportList(params)

    if (res.code === 0 && res.details) {
      tableData.value = normalizeReportRows(res.details.data || [])
      pagination.total = res.details.total || 0
    } else {
      Message.error(res.message || '获取报表列表失败')
    }
  } catch (error: any) {
    console.error('获取报表列表失败:', error)
    Message.error(error.message || '获取报表列表失败')
  } finally {
    loading.value = false
  }
}

// 处理表单模型更新
const handleFormModelUpdate = (value: any) => {
  formModel.value = {
    ...formModel.value,
    ...value,
  }
}

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

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

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

// 打开生成报表弹窗
const handleOpenGenerateModal = () => {
  generateForm.value = {
    data_source: '',
    metric_id: '',
    target_identities: [],
    timeRange: [],
    n: 10,
    rank_aggregate: 'avg',
    order: 'desc',
    title: '',
  }
  generateModalVisible.value = true
}

// 关闭生成报表弹窗
const handleCloseGenerateModal = () => {
  generateModalVisible.value = false
}

// 生成报表
const handleGenerate = async () => {
  // 验证必填项
  if (!generateForm.value.data_source) {
    Message.warning('请选择数据源')
    return
  }

  if (generateForm.value.data_source !== 'alert' && !generateForm.value.metric_id) {
    Message.warning('请选择指标')
    return
  }

  if (generateForm.value.data_source !== 'alert' && generateForm.value.target_identities.length === 0) {
    Message.warning('请选择目标标识')
    return
  }

  if (!generateForm.value.timeRange || generateForm.value.timeRange.length !== 2) {
    Message.warning('请选择时间范围')
    return
  }

  generating.value = true

  try {
    const params: TopNReportParams = {
      data_source: generateForm.value.data_source as any,
      metric_id: generateForm.value.data_source === 'alert' ? 'alert_frequency' : generateForm.value.metric_id,
      target_identities: generateForm.value.data_source === 'alert' ? [] : generateForm.value.target_identities,
      start_time: generateForm.value.timeRange[0],
      end_time: generateForm.value.timeRange[1],
    }

    if (generateForm.value.n) {
      params.n = generateForm.value.n
    }

    if (generateForm.value.rank_aggregate) {
      params.rank_aggregate = generateForm.value.rank_aggregate as any
    }

    if (generateForm.value.order) {
      params.order = generateForm.value.order as any
    }

    const res = await generateReport({
      report_type: ReportType.TOPN,
      title: generateForm.value.title || undefined,
      params,
    })

    if (res.code === 0 && res.details) {
      if (res.details.status === 'success') {
        Message.success('报表生成成功')
        generateModalVisible.value = false
        fetchList()
      } else if (res.details.status === 'failed') {
        Message.error(res.details.error_message || '报表生成失败')
      } else {
        Message.info('报表正在生成中，请稍后刷新查看')
        generateModalVisible.value = false
        fetchList()
      }
    } else {
      Message.error(res.message || '报表生成失败')
    }
  } catch (error: any) {
    console.error('生成报表失败:', error)
    Message.error(error.message || '生成报表失败')
  } finally {
    generating.value = false
  }
}

// 查看内容
const handleViewContent = async (record?: ReportRecord) => {
  const targetRecord = record || selectedRecord.value
  if (!targetRecord) return

  contentLoading.value = true
  contentModalVisible.value = true
  contentModalTitle.value = targetRecord.title
  reportContent.value = null

  try {
    const res = await fetchReportContent(targetRecord.id)

    if (res.code === 0 && res.details) {
      reportContent.value = res.details

      // 渲染图表
      if (res.details.ranking) {
        await nextTick()
        renderChart(res.details.ranking)
      }
    } else {
      Message.error(res.message || '获取报表内容失败')
    }
  } catch (error: any) {
    console.error('获取报表内容失败:', error)
    Message.error(error.message || '获取报表内容失败')
  } finally {
    contentLoading.value = false
  }
}

// 导出报表
const handleExport = async (format: ReportExportFormat, record?: ReportRecord) => {
  const targetRecord = record || selectedRecord.value
  if (!targetRecord) {
    Message.warning('请选择要导出的报表')
    return
  }

  if (targetRecord.status !== 'success') {
    Message.warning('只能导出生成成功的报表')
    return
  }

  exporting.value = true

  try {
    await downloadReportFile(targetRecord, format)

    Message.success('导出成功')
  } catch (error: any) {
    console.error('导出失败:', error)
    Message.error(error.message || '导出失败')
  } finally {
    exporting.value = false
  }
}

// 渲染图表
const renderChart = (ranking: any[]) => {
  if (!chartRef.value || ranking.length === 0) return

  if (chartInstance) {
    chartInstance.dispose()
  }

  chartInstance = echarts.init(chartRef.value)

  const option: echarts.EChartsOption = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true,
    },
    xAxis: {
      type: 'value',
    },
    yAxis: {
      type: 'category',
      data: ranking.map((item: any) => item.target ?? item.identity ?? item.target_identity ?? '').reverse(),
    },
    series: [
      {
        name: '值',
        type: 'bar',
        data: ranking.map((item: any) => item.value).reverse(),
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            { offset: 0, color: '#188df0' },
            { offset: 1, color: '#83bff6' },
          ]),
        },
      },
    ],
  }

  chartInstance.setOption(option)
}

// 初始化
fetchList()
</script>

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

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

  .chart-container {
    height: 400px;
    width: 100%;
    margin-bottom: 20px;
  }

  .loading-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 200px;
  }

  .target-id-hint {
    margin-top: 6px;
    font-size: 12px;
    color: var(--color-text-3);
    line-height: 1.4;
  }
}
</style>
