/**
 * Снимок прогона планировщика (JSON из `scheduler_runs.result_json`).
 * Дублирует контракт `backend/src/types/scheduler-run-snapshot.ts` для UI.
 */

export interface ServerRestPingSnapshot {
  serverId: number
  name: string
  host: string
  ok: boolean
  latencyMs?: number | null
  error?: string
}

export interface ServersRestPingRunSnapshot {
  v: number
  job: "servers_rest_ping"
  sampledAt: string
  skipped?: boolean
  fatalError?: string
  servers: ServerRestPingSnapshot[]
}

export type AlertEngineRuleDiagSnapshot = {
  ruleId: string
  inGroup: boolean
  evalHit: boolean
  hitTransition?: "problem" | "recovery" | "neutral"
  hitMessage?: string
  stabilityOk: boolean
  cooldownOk: boolean
  telegramOk: boolean
  blocked?:
    | "no_hit"
    | "stability"
    | "cooldown"
    | "no_telegram"
    | "dedupe_positive"
    | "in_group"
}

/** Сводка прогона движка оповещений (JSON из `scheduler_runs` для job `alert_engine`). */
export interface AlertEngineRunSnapshot {
  v: number
  job: "alert_engine"
  sampledAt: string
  rulesChecked: number
  standaloneFires: number
  groupFires: number
  skippedNoTelegram: boolean
  errors?: string[]
  ruleDiag?: AlertEngineRuleDiagSnapshot[]
}

export interface GreBgpSnapshotRunSnapshot {
  v: number
  job: "gre_bgp"
  sampledAt: string
  skipped?: boolean
  fatalError?: string
  greWritten: number
  bgpWritten: number
  errors?: string[]
}

export interface InternetPathRunSnapshot {
  v: number
  job: "internet_path"
  sampledAt: string
  homes: number
  snapshotSaved: boolean
  fatalError?: string
}

export interface CertificatesRenewRunSnapshot {
  v: number
  job: "certificates_renew"
  sampledAt: string
  skipped?: boolean
  fatalError?: string
  checked: number
  renewed: number
  skippedTargets: number
  errors: string[]
}

export interface BackupsRunSnapshot {
  v: number
  job: "backups"
  sampledAt: string
  skipped?: boolean
  due: boolean
  created: number
  failures: number
  pruned: number
  errors?: string[]
  fatalError?: string
}

export type SchedulerRunSnapshot =
  | TrafficRunSnapshot
  | ResourcesRunSnapshot
  | PingRunSnapshot
  | SpeedScheduledRunSnapshot
  | ServersRestPingRunSnapshot
  | GreBgpSnapshotRunSnapshot
  | InternetPathRunSnapshot
  | CertificatesRenewRunSnapshot
  | BackupsRunSnapshot
  | AlertEngineRunSnapshot

export interface TrafficServerSnapshot {
  serverId: number
  name: string
  host: string
  ok: boolean
  error?: string
  interfaces?: number
  sumRxMbps?: number
  sumTxMbps?: number
}

export interface TrafficRunSnapshot {
  v: number
  job: "traffic"
  sampledAt: string
  skipped?: boolean
  fatalError?: string
  servers: TrafficServerSnapshot[]
}

export interface ResourceServerSnapshot {
  serverId: number
  name: string
  host: string
  status: "online" | "offline"
  error?: string
  cpuLoadPct?: number
  memUsedMb?: number
  memTotalMb?: number
  memUsedPct?: number
  diskFreeMb?: number
  diskTotalMb?: number
  uptimeSeconds?: number
  boardName?: string
  rosVersion?: string
}

export interface ResourcesRunSnapshot {
  v: number
  job: "uptime_resources"
  sampledAt: string
  skipped?: boolean
  fatalError?: string
  servers: ResourceServerSnapshot[]
}

export interface PingProbeSnapshot {
  probeId: string
  name: string
  target: string
  srcServerId: number
  srcServerName: string
  srcInterface: string
  ok: boolean
  rttMs: number | null
  lossPct: number
  status: "up" | "warn" | "down"
  error?: string
}

export interface PingRunSnapshot {
  v: number
  job: "uptime_ping"
  sampledAt: string
  skipped?: boolean
  fatalError?: string
  probes: PingProbeSnapshot[]
  skippedByInterval?: number
}

export interface SpeedRunSnapshot {
  probeId: string
  srcServerId: number
  srcServerName: string
  dstServerId: number
  dstServerName: string
  srcInterface: string
  dstInterface: string
  protocol: string
  direction: string
  durationSec: number
  ok: boolean
  txAvgMbps?: number | null
  rxAvgMbps?: number | null
  pingRttMs?: number | null
  pingLossPct?: number | null
  pingError?: string | null
  error?: string
}

export interface SpeedScheduledRunSnapshot {
  v: number
  job: "uptime_speed"
  sampledAt: string
  runs: SpeedRunSnapshot[]
}

export function parseSchedulerRunSnapshot(raw: string | null | undefined): SchedulerRunSnapshot | null {
  if (raw == null || raw.trim() === "") return null
  try {
    const o = JSON.parse(raw) as { v?: unknown; job?: string }
    if (o?.v !== 1 || typeof o.job !== "string") return null
    return o as SchedulerRunSnapshot
  } catch {
    return null
  }
}
