/**
 * 服务器硬件监控页专用：对接 DC-Hardware 服务（/DC-Hardware/v1）。
 * 与「机房设备监控」等业务区分，勿混用命名。
 */
import { request } from '@/api/request'

const HW_PREFIX = '/DC-Hardware/v1'

/** 与 bsm-sdk 成功响应一致：业务数据在 details */
export interface HostHardwareApiEnvelope<T = unknown> {
  code?: number | string
  message?: string
  details?: T
}

export interface HostHardwareDeviceDetailPayload {
  device: HostHardwareDevice
  status: HostHardwareStatus | null
}

export interface HostHardwareDevice {
  id: string
  name?: string
  ip: string
  /** 设备类别，如 server/switch/storage；未返回时前端可按 server 展示 */
  type?: string
  protocol: string
  manufacturer?: string
  model?: string
  serial_number?: string
  username?: string
  password?: string
  port?: number
  snmp_port?: number
  community?: string
  snmp_version?: string
  snmp_oids?: string
  redfish_base_url?: string
  redfish_tls_skip_verify?: boolean
  ipmi_timeout_seconds?: number
  snmp_timeout_seconds?: number
  redfish_timeout_seconds?: number
  ipmi_collect_enabled?: boolean
  snmp_collect_enabled?: boolean
  redfish_collect_enabled?: boolean
  collect_interval?: number
  asset_id?: string
  server_identity?: string
  enabled?: boolean
  status?: string
  tags?: string
  description?: string
  extra_config?: string
}

/** 创建/更新 DC-Hardware 设备（与 CreateDeviceRequest 一致；密码在更新时为空则不修改） */
export interface HostHardwareDeviceUpsert {
  name: string
  ip: string
  /** 省略或空则服务端默认 server */
  type?: string
  protocol: string
  username?: string
  password?: string
  port?: number
  snmp_port?: number
  community?: string
  snmp_version?: string
  snmp_oids?: string
  redfish_base_url?: string
  redfish_tls_skip_verify?: boolean
  location?: string
  description?: string
  tags?: string
  asset_id?: string
  server_identity?: string
  extra_config?: string
  ipmi_timeout_seconds?: number
  snmp_timeout_seconds?: number
  redfish_timeout_seconds?: number
  ipmi_collect_enabled?: boolean
  snmp_collect_enabled?: boolean
  redfish_collect_enabled?: boolean
  collect_interval?: number
  /** 是否启用监控调度 */
  enabled?: boolean
}

export interface HostHardwareDeviceListPayload {
  total: number
  page: string | number
  page_size: string | number
  data: HostHardwareDevice[]
}

export interface HostHardwareStatus {
  id?: string
  device_id?: string
  status?: string
  power_status?: string
  cpu_status?: string
  memory_status?: string
  disk_status?: string
  fan_status?: string
  temperature_status?: string
  network_status?: string
  psu_status?: string
  raid_status?: string
  last_check_time?: string
  error_message?: string
  raw_data?: string
}

export interface HostHardwareMetricsRow {
  id?: string
  device_id?: string
  metric_name: string
  metric_type: string
  metric_value: number
  unit?: string
  status?: string
  threshold?: number
  location?: string
  collection_time?: string
}

export interface HostHardwareLatestCollectionPayload {
  device_id: string
  collected_at?: string | null
  status: HostHardwareStatus | null
  metrics: HostHardwareMetricsRow[]
  timescaledb?: boolean
  message?: string
  server_identity?: string
}

interface RawCollectionMetric {
  name?: string
  type?: string
  value?: number
  unit?: string
  status?: string
  threshold?: number
  location?: string
}

interface RawCollectionRoot {
  metrics?: RawCollectionMetric[]
}

export interface NormalizedHostHardwareMetric {
  name: string
  type: string
  value: number
  unit: string
  status: string
  threshold?: number
  location?: string
}

export interface HostHardwareMetricHistoryPayload {
  device_id: string
  metric_name: string
  start_time?: string
  end_time?: string
  data: HostHardwareMetricsRow[]
  timescaledb?: boolean
  message?: string
}

export interface HostHardwareStatisticsRow {
  device_id: string
  stat_date: string
  online_time?: number
  offline_time?: number
  warning_count?: number
  critical_count?: number
  avg_temperature?: number
  max_temperature?: number
  min_temperature?: number
  avg_fan_speed?: number
  avg_power_usage?: number
  max_power_usage?: number
  total_check_count?: number
  success_check_count?: number
  failed_check_count?: number
  availability?: number
}

export function isHostHardwareApiSuccess(res: HostHardwareApiEnvelope | null | undefined): boolean {
  const c = res?.code
  if (c === 0 || c === '0') return true
  // 少数网关/代理以 200 表示业务成功
  if (c === 200 || c === '200') return true
  return false
}

export function unwrapHostHardwareDetails<T>(res: (HostHardwareApiEnvelope<T> & { data?: T }) | null | undefined): T | null {
  if (!res || !isHostHardwareApiSuccess(res)) return null
  // 部分网关/SDK 将载荷放在 data 而非 details，与 logs 等模块一致做兼容
  return res.details ?? res.data ?? null
}

/** 按 server_identity 拉取最新一整轮采集（JWT） */
export function fetchHostHardwareLatestCollection(serverIdentity: string) {
  return request.get<HostHardwareApiEnvelope<HostHardwareLatestCollectionPayload>>(
    `${HW_PREFIX}/devices/by-server-identity/collection/latest`,
    { params: { server_identity: serverIdentity } }
  )
}

/** 设备详情（含最新一条 status） */
export function fetchHostHardwareDevice(deviceId: string) {
  return request.get<HostHardwareApiEnvelope<HostHardwareDeviceDetailPayload>>(`${HW_PREFIX}/devices/${encodeURIComponent(deviceId)}`)
}

/** 分页列表（可按 type / status / asset_id 筛选） */
export function fetchHostHardwareDeviceList(params?: {
  type?: string
  status?: string
  asset_id?: string
  page?: number
  page_size?: number
}) {
  return request.get<HostHardwareApiEnvelope<HostHardwareDeviceListPayload>>(`${HW_PREFIX}/devices`, {
    params,
  })
}

/** 创建设备 */
export function createHostHardwareDevice(data: HostHardwareDeviceUpsert) {
  return request.post<HostHardwareApiEnvelope<HostHardwareDevice>>(`${HW_PREFIX}/devices`, data)
}

/** 更新设备（全量必填字段；密码留空则不修改） */
export function updateHostHardwareDevice(deviceId: string, data: HostHardwareDeviceUpsert) {
  return request.put<HostHardwareApiEnvelope<HostHardwareDevice>>(`${HW_PREFIX}/devices/${encodeURIComponent(deviceId)}`, data)
}

/** 异步立即采集 */
export function triggerHostHardwareCollect(deviceId: string) {
  return request.post<HostHardwareApiEnvelope<string>>(`${HW_PREFIX}/devices/${encodeURIComponent(deviceId)}/collect`)
}

/** 启用监控 */
export function enableHostHardwareDevice(deviceId: string) {
  return request.post<HostHardwareApiEnvelope<string>>(`${HW_PREFIX}/devices/${encodeURIComponent(deviceId)}/enable`)
}

/** 禁用监控 */
export function disableHostHardwareDevice(deviceId: string) {
  return request.post<HostHardwareApiEnvelope<string>>(`${HW_PREFIX}/devices/${encodeURIComponent(deviceId)}/disable`)
}

/** 单指标历史曲线（JWT） */
export function fetchHostHardwareMetricHistory(deviceId: string, metricName: string, startTime?: string, endTime?: string) {
  return request.get<HostHardwareApiEnvelope<HostHardwareMetricHistoryPayload>>(
    `${HW_PREFIX}/metrics/devices/${encodeURIComponent(deviceId)}/history`,
    {
      params: {
        metric_name: metricName,
        ...(startTime ? { start_time: startTime } : {}),
        ...(endTime ? { end_time: endTime } : {}),
      },
    }
  )
}

/** 日汇总统计 */
export function fetchHostHardwareStatistics(deviceId: string, startDate?: string, endDate?: string) {
  return request.get<HostHardwareApiEnvelope<HostHardwareStatisticsRow[]>>(`${HW_PREFIX}/metrics/statistics`, {
    params: {
      device_id: deviceId,
      ...(startDate ? { start_date: startDate } : {}),
      ...(endDate ? { end_date: endDate } : {}),
    },
  })
}

/**
 * 合并 API metrics 与 raw_data 兜底（无时序库时 metrics 可能为空）
 */
export function normalizeHostHardwareMetrics(
  status: HostHardwareStatus | null | undefined,
  metricsFromApi: HostHardwareMetricsRow[] | null | undefined
): NormalizedHostHardwareMetric[] {
  const fromApi = metricsFromApi ?? []
  if (fromApi.length > 0) {
    return fromApi.map((m) => ({
      name: m.metric_name,
      type: m.metric_type,
      value: m.metric_value,
      unit: m.unit ?? '',
      status: m.status ?? 'ok',
      threshold: m.threshold,
      location: m.location,
    }))
  }
  const raw = status?.raw_data
  if (!raw || typeof raw !== 'string') return []
  try {
    const parsed = JSON.parse(raw) as RawCollectionRoot
    const arr = parsed.metrics
    if (!Array.isArray(arr)) return []
    return arr
      .map((m) => ({
        name: String(m.name ?? ''),
        type: String(m.type ?? ''),
        value: typeof m.value === 'number' ? m.value : Number(m.value) || 0,
        unit: String(m.unit ?? ''),
        status: String(m.status ?? 'ok'),
        threshold: m.threshold,
        location: m.location ? String(m.location) : undefined,
      }))
      .filter((m) => m.name || m.type)
  } catch {
    return []
  }
}
