import type { AdapterStatus } from './collector-types'

export type OverallHealth = 'healthy' | 'stale' | 'error' | 'unknown'
export type Reachability = 'reachable' | 'stale' | 'error' | 'unknown'

export interface AdapterHealthRow {
  id: string
  reachability: Reachability
  lastSuccess: number | null
  lastPollDurationMs: number | null
  consecutiveErrors: number
  lastError: string | null
}

export function overallHealth(adapters: AdapterStatus[]): OverallHealth {
  if (adapters.length === 0) return 'unknown'
  if (adapters.some((adapter) => adapter.lastError || adapter.consecutiveErrors > 0)) return 'error'
  if (adapters.some((adapter) => adapter.stale)) return 'stale'
  return 'healthy'
}

export interface HealthSummary {
  status: OverallHealth
  /** Adapters responsible for a non-healthy status, worst first. */
  failing: string[]
  /** One line naming what is wrong, ready to read without opening the health page. */
  detail: string
}

/** The status a chip may show, with the reason attached — a bare "error" tells nobody anything. */
export function healthSummary(
  adapters: AdapterStatus[] | undefined,
  fetchError: string | null = null,
): HealthSummary {
  if (fetchError !== null) {
    return { status: 'error', failing: [], detail: `The collector could not be reached: ${fetchError}` }
  }
  if (!adapters) return { status: 'unknown', failing: [], detail: 'The collector has not answered yet.' }
  if (adapters.length === 0) {
    return { status: 'unknown', failing: [], detail: 'The collector reports no adapters at all.' }
  }

  const status = overallHealth(adapters)
  if (status === 'error') {
    const broken = adapters.filter((adapter) => adapter.lastError || adapter.consecutiveErrors > 0)
    const reasons = broken.map((adapter) => `${adapter.id}: ${adapter.lastError ?? `${adapter.consecutiveErrors} failed polls`}`)
    return { status, failing: broken.map((adapter) => adapter.id), detail: reasons.join(' · ') }
  }
  if (status === 'stale') {
    const stale = adapters.filter((adapter) => adapter.stale)
    return {
      status,
      failing: stale.map((adapter) => adapter.id),
      detail: `${stale.map((adapter) => adapter.id).join(', ')} ${stale.length === 1 ? 'has' : 'have'} not reported recently.`,
    }
  }

  return { status, failing: [], detail: `All ${adapters.length} adapters are reporting.` }
}

/** Chip text: the status alone is never enough to act on, so it names the failing adapters. */
export function healthChipLabel(summary: HealthSummary): string {
  if (summary.failing.length === 0) return summary.status
  const named = summary.failing.slice(0, 2).join(', ')
  const rest = summary.failing.length - Math.min(2, summary.failing.length)
  return `${summary.status}: ${named}${rest > 0 ? ` +${rest}` : ''}`
}

export function adapterHealthRow(adapter: AdapterStatus): AdapterHealthRow {
  const reachability: Reachability = adapter.lastError || adapter.consecutiveErrors > 0
    ? 'error'
    : adapter.stale
      ? 'stale'
      : adapter.lastSuccess === undefined
        ? 'unknown'
        : 'reachable'
  return {
    id: adapter.id,
    reachability,
    lastSuccess: adapter.lastSuccess ?? null,
    lastPollDurationMs: adapter.lastPollDurationMs ?? null,
    consecutiveErrors: adapter.consecutiveErrors,
    lastError: adapter.lastError ?? null,
  }
}
