import { request } from '@/api/request'
import SafeStorage, { AppStorageKey } from '@/utils/safeStorage'

// ============ 通用响应类型 ============

export interface ApiResponse<T = any> {
  code: number
  details: T
  message?: string
}

// ============ 报表类型枚举 ============

export enum ReportType {
  TOPN = 'topn',
  STATISTICS = 'statistics',
  TRAFFIC = 'traffic',
  FAULT = 'fault',
  SERVER = 'server',
  NETWORK_DEVICE = 'network_device',
  OPERATIONS = 'operations',
  EVIDENCE = 'evidence',
}

export enum ReportStatus {
  PENDING = 'pending',
  RUNNING = 'running',
  SUCCESS = 'success',
  FAILED = 'failed',
}

// ============ 报表记录接口 ============

export interface ReportRecord {
  id: number
  /** 列表接口可能包含已下线或自动生成的报表类型 */
  report_type: ReportType | string
  title: string
  description?: string
  status: ReportStatus
  error_message?: string
  params_json?: Record<string, any>
  result_summary_json?: Record<string, any>
  file_path?: string
  file_size?: number
  file_mime?: string
  started_at?: string
  finished_at?: string
  created_at: string
  updated_at: string
}

export interface ReportListParams {
  page?: number
  size?: number
  report_type?: ReportType
  status?: ReportStatus
  keyword?: string
  created_from?: string
  created_to?: string
}

export interface PageResult<T> {
  total: number
  page: number
  page_size: number
  data: T[]
}

export type ReportExportFormat = 'csv' | 'xlsx' | 'pdf'

export interface DownloadedReport {
  blob: Blob
  fileName: string
}

// ============ 报表生成参数接口 ============

export interface TrafficReportParams {
  /** topology：拓扑/NetFlow；snmp_devices：多设备 SNMP 接口流量汇总 */
  traffic_mode?: 'topology' | 'snmp_devices'
  /** traffic_mode=snmp_devices 时必填，service_identity 列表 */
  service_identities?: string[]
  topology_id?: number
  link_id?: number
  node_id?: string
  granularity?: 'minute' | 'hour' | 'day' | 'month'
  start_time: string
  end_time: string
  report_shape: 'summary' | 'detail' | 'trend' | 'top'
  detail_limit?: number
  trend_granularity?: 'minute' | 'hour' | 'day' | 'month'
  top_order_by?:
    | 'total_bytes'
    | 'total_in_bytes'
    | 'total_out_bytes'
    | 'total_packets'
    | 'avg_latency'
    | 'avg_packet_loss'
    | 'total_connections'
  top_limit?: number
}

export interface FaultReportParams {
  fault_data_source?: 'collector_log' | 'alert' | 'hybrid'
  start_time: string
  end_time: string
  service_identities?: string[]
  status?: 'success' | 'failed' | 'timeout'
  keyword?: string
  group_by?: 'none' | 'service_identity' | 'day'
  alert_severities?: string[]
  alert_label_filters?: Record<string, string>
  include_raw_messages?: boolean
  detail_limit?: number
}

export interface ServerReportParams {
  server_ids?: number[]
  server_identities?: string[]
  start_time: string
  end_time: string
  columns?: ('availability' | 'last_check_time' | 'cpu' | 'memory_phys' | 'memory_virt' | 'disk_io' | 'disk_usage' | 'daily_alerts')[]
  availability_rule?: 'metrics_presence' | 'server_status'
  include_daily_alerts?: boolean
}

/** POST /reports/generate report_type=network_device */
export interface NetworkDeviceReportParams {
  network_device_service_ids?: number[]
  service_identities?: string[]
  start_time: string
  end_time: string
  columns?: string[]
  include_daily_alerts?: boolean
}

export interface StatisticsReportParams {
  data_source: 'dc-host' | 'dc-network' | 'dc-database' | 'dc-middleware'
  metric_id: string
  target_identities: string[]
  start_time: string
  end_time: string
  output_mode: 'scalar' | 'timeseries'
  scalar_aggregations?: ('avg' | 'max' | 'min' | 'sum' | 'count')[]
  interval?: string
  bucket_aggregation?: 'avg' | 'max' | 'min' | 'sum'
}

export interface HistoryReportParams {
  data_source: 'dc-host' | 'dc-network' | 'dc-database' | 'dc-middleware'
  metric_names: string[]
  target_identities: string[]
  start_time: string
  end_time: string
  interval: string
  bucket_aggregation: 'avg' | 'max' | 'min' | 'sum'
  series_layout?: string
}

export interface TopNReportParams {
  data_source: 'dc-host' | 'dc-network' | 'dc-database' | 'dc-middleware' | 'alert'
  metric_id: string
  target_identities: string[]
  start_time: string
  end_time: string
  n?: number
  rank_aggregate?: 'avg' | 'max' | 'min' | 'last'
  order?: 'desc' | 'asc'
}

/** 证据导出事件行 */
export interface EvidenceEvent {
  event_time: string
  action: string
  actor?: string
  message?: string
  source_id?: string
  details?: Record<string, any>
}

/** POST /reports/evidence/export */
export interface EvidenceExportParams {
  incident_id: number
  resource_uid?: string
  business_system_id?: number
  title?: string
  timeline?: EvidenceEvent[]
  notifications?: EvidenceEvent[]
  ticket_logs?: EvidenceEvent[]
  audit_logs?: EvidenceEvent[]
}

export interface GenerateReportParams {
  report_type: ReportType
  title?: string
  description?: string
  params:
    | TrafficReportParams
    | FaultReportParams
    | ServerReportParams
    | NetworkDeviceReportParams
    | StatisticsReportParams
    | HistoryReportParams
    | TopNReportParams
    | Record<string, any>
}

// ============ 报表生成接口（新版） ============

/** 获取报表记录列表 */
export const fetchReportList = (params: ReportListParams) =>
  request.get<ApiResponse<PageResult<ReportRecord>>>('/DC-Control/v1/reports', { params })

/** 获取报表详情 */
export const fetchReportDetail = (id: number) => request.get<ApiResponse<ReportRecord>>(`/DC-Control/v1/reports/${id}`)

/** 同步生成报表（topn / statistics / traffic / fault / server / network_device） */
export const generateReport = (data: GenerateReportParams) =>
  request.post<ApiResponse<ReportRecord>>('/DC-Control/v1/reports/generate', data)

/** 异步生成报表任务 */
export const createReportAsyncJob = (data: GenerateReportParams) =>
  request.post<ApiResponse<ReportRecord>>('/DC-Control/v1/reports/jobs', data)

/** 生成 incident 证据导出记录 */
export const exportEvidenceReport = (data: EvidenceExportParams) =>
  request.post<ApiResponse<ReportRecord>>('/DC-Control/v1/reports/evidence/export', data)

/** 指标发现（时间窗内有样本的 metric_name） */
export const fetchReportMetricsAvailable = (params: {
  data_source: string
  start_time: string
  end_time: string
  identities?: string
  keyword?: string
  limit?: number
}) =>
  request.get<ApiResponse<{ data_source: string; items: any[]; registry: any[] }>>('/DC-Control/v1/reports/metrics/available', { params })

/** 逻辑指标目录（Registry） */
export const fetchReportMetricsRegistry = (params: { data_source: string }) =>
  request.get<ApiResponse<{ data_source: string; metrics: any[] }>>('/DC-Control/v1/reports/metrics/registry', { params })

/** 查看报表内容 */
export const fetchReportContent = (id: number) => request.get<ApiResponse<Record<string, any>>>(`/DC-Control/v1/reports/${id}/content`)

/** 原始 ArrayBuffer → 下载用 Blob；xlsx 校验 ZIP 魔数 PK，PDF 校验 %PDF- */
function exportBufferToBlob(ab: ArrayBuffer, format: ReportExportFormat, contentType: string | null): Blob {
  const u8 = new Uint8Array(ab)
  if (format === 'xlsx') {
    const okZip = u8.length >= 4 && u8[0] === 0x50 && u8[1] === 0x4b
    if (!okZip) {
      const head = new TextDecoder('utf-8', { fatal: false }).decode(u8.slice(0, 4096)).trim()
      let detail = '服务器返回的不是有效的 xlsx（应为 ZIP，文件头 PK）。'
      if (head.startsWith('{') || head.startsWith('[')) {
        try {
          const j = JSON.parse(head) as { message?: string }
          if (j.message) detail = j.message
        } catch {
          /* ignore */
        }
      } else if (head.startsWith('<')) {
        detail = '服务器返回了 HTML 而非文件，请检查网关、反向代理或登录态。'
      }
      throw new Error(`导出失败：${detail}`)
    }
    const mime =
      contentType && /spreadsheet|zip|octet-stream/i.test(contentType)
        ? contentType
        : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    return new Blob([ab], { type: mime })
  }
  if (format === 'pdf') {
    const okPdf = u8.length >= 5 && u8[0] === 0x25 && u8[1] === 0x50 && u8[2] === 0x44 && u8[3] === 0x46 && u8[4] === 0x2d
    if (!okPdf) {
      throw new Error('导出失败：服务器返回的不是有效的 PDF。')
    }
    const mime = contentType && /pdf/i.test(contentType) ? contentType : 'application/pdf'
    return new Blob([ab], { type: mime })
  }
  const mime = contentType && /csv|text|plain/i.test(contentType) ? contentType : 'text/csv;charset=utf-8'
  return new Blob([ab], { type: mime })
}

function parseContentDispositionFileName(value: string | null): string | undefined {
  if (!value) return undefined

  const utf8FileName = value.match(/filename\*=UTF-8''([^;]+)/i)
  if (utf8FileName) {
    try {
      return decodeURIComponent(utf8FileName[1])
    } catch {
      // 编码异常时继续读取普通文件名
    }
  }

  return value.match(/filename="([^"]+)"/i)?.[1]
}

function normalizeReportFileName(fileName: string | undefined, id: number, format: ReportExportFormat): string {
  const defaultName = `report_${id}.${format}`
  if (!fileName) return defaultName

  let name = fileName.split(/[\\/]/).pop() || ''
  name = name
    .replace(/[\u0000-\u001F\u007F-\u009F\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/g, '')
    .replace(/[<>:"/\\|?*]/g, '_')
    .replace(/[ .]+$/, '')

  const extensionIndex = name.lastIndexOf('.')
  if (extensionIndex > 0) {
    name = name.slice(0, extensionIndex).replace(/[ .]+$/, '')
  }
  if (!name) return defaultName

  const reservedName = /^(con|prn|aux|nul|com[1-9¹²³]|lpt[1-9¹²³])$/i
  if (reservedName.test(name.split('.')[0])) {
    name = `_${name}`
  }

  return `${name}.${format}`
}

/**
 * 报表文件导出：使用 fetch + arrayBuffer，绕过 axios 拦截器与 Blob 中间态，
 * 避免网络面板里已是合法 xlsx（PK…）但落盘文件损坏的情况。
 */
export const exportReport = async (id: number, format: ReportExportFormat = 'csv'): Promise<DownloadedReport> => {
  const base = String(import.meta.env.VITE_API_BASE_URL || '').replace(/\/$/, '')
  const url = `${base}/DC-Control/v1/reports/${id}/export?format=${encodeURIComponent(format)}`
  const token = SafeStorage.get(AppStorageKey.TOKEN)
  const headers: Record<string, string> = {
    Workspace: String(import.meta.env.VITE_APP_WORKSPACE || ''),
  }
  if (token) headers.Authorization = String(token)

  const r = await fetch(url, { method: 'GET', headers })
  const ab = await r.arrayBuffer()
  if (!r.ok) {
    const head = new TextDecoder('utf-8', { fatal: false }).decode(new Uint8Array(ab).slice(0, 4096))
    let msg = `导出失败 (HTTP ${r.status})`
    try {
      const j = JSON.parse(head.trim()) as { message?: string }
      if (j.message) msg = j.message
    } catch {
      /* ignore */
    }
    throw new Error(msg)
  }
  return {
    blob: exportBufferToBlob(ab, format, r.headers.get('content-type')),
    fileName: normalizeReportFileName(parseContentDispositionFileName(r.headers.get('content-disposition')), id, format),
  }
}

// ============ 监测指标类接口（旧版兼容） ============

/** 监测指标TOPN */
export const fetchMetricsTopN = (params: any) => request.get('/DC-Control/v1/reports/metrics/topn', { params })

/** 监测指标汇总 */
export const fetchMetricsSummary = (params: any) => request.get('/DC-Control/v1/reports/metrics/summary', { params })

/** 监测指标汇总导出 */
export const exportMetricsSummary = (params: any) => request.get('/DC-Control/v1/reports/metrics/export', { params, responseType: 'blob' })

// ============ 流量报表接口（旧版兼容） ============

/** 流量报表汇总 */
export const fetchTrafficSummary = (params: any) => request.get('/DC-Control/v1/reports/traffic/summary', { params })

/** 流量报表趋势 */
export const fetchTrafficTrend = (params: any) => request.get('/DC-Control/v1/reports/traffic/trend', { params })

/** 流量报表导出 */
export const exportTrafficReport = (params: any) => request.get('/DC-Control/v1/reports/traffic/export', { params, responseType: 'blob' })

// ============ 状态报表接口（旧版兼容） ============

/** 服务器状态报表 */
export const fetchServerStatus = (params: any) => request.get('/DC-Control/v1/reports/servers/status', { params })

/** 网络设备状态报表 */
export const fetchNetworkDeviceStatus = (params: any) => request.get('/DC-Control/v1/reports/network-devices/status', { params })
