/**
 * Structural mirror of collector's wire protocol (collector/src/schema.ts +
 * collector/src/state.ts). Duplicated locally, not imported — `collector` sits
 * outside the pnpm workspace glob (`apps/*`, `packages/*`).
 */
export type Severity = 'act' | 'warn' | 'info'

export type Kind = 'alert' | 'ci' | 'halt' | 'decision' | 'limit' | 'gate' | 'progress' | 'build'

export interface ActionRef {
  verb: string
  args: Record<string, string>
  label: string
  recommended?: boolean
}

export interface DecisionOption {
  label: string
  recommended?: boolean
}

export interface Decision {
  question: string
  options: DecisionOption[]
  freeText: boolean
  context: string
  waitingSince: string
}

export interface Item {
  id: string
  source: string
  project?: string
  reconciliationScope?: string
  severity: Severity
  kind: Kind
  title: string
  detail: string
  ts: string
  actions: ActionRef[]
  decision?: Decision
}

export interface Panel {
  id: string
  ts: string
  data: unknown
}

export interface AdapterStatus {
  id: string
  interval: number
  lastAttempt?: number
  lastSuccess?: number
  lastError?: string
  lastPollDurationMs?: number
  consecutiveErrors: number
  stale: boolean
}

export type Delta =
  | { type: 'item'; item: Item }
  | { type: 'panel'; panel: Panel }
  | { type: 'item-resolved'; id: string }

export interface StateResponse {
  panels: Panel[]
  adapters: AdapterStatus[]
}

export interface ItemsResponse {
  items: Item[]
}

export interface HookInventoryItem {
  id: string
  source: string
  scope: string
  event: string
  matcher: string | null
  command: string
  commandPath: string | null
  exists: boolean
  executable: boolean
  runtime: string | null
  runtimeResolves: boolean | null
  status: 'OK' | 'DEAD' | 'UNOBSERVED'
  problem: string | null
  lastExecutionAt: string | null
  evidenceSource: string | null
}

export type HookControlId = 'background-jobs-blocker'
export type HookControlsPersistence = 'confirmed' | 'indeterminate'
export type HookControlsIssue = {
  code: 'invalid-hook-controls' | 'wrong-hook-controls-version'
  detail: string
  repairable: boolean
}
export interface HookControlsResponse {
  controls: { version: 'hook-controls/v1'; hooks: Record<HookControlId, boolean> }
  issue: null | HookControlsIssue
  persistence?: HookControlsPersistence
  persistenceDetail?: string
}

export interface HookInventoryResponse {
  generatedAt: string
  sources: string[]
  sourceErrors: Array<{ source: string; error: string }>
  hooks: HookInventoryItem[]
}

export type HookFireStatus = 'OBSERVING' | 'ACTIVE' | 'SUSPECT' | 'REMOVAL_CANDIDATE'

export interface HookFireModuleRow {
  module: string
  event: string
  matcher: string | null
  inManifest: boolean
  fires24h: number
  fires7d: number
  fires30d: number
  lastFiredAt: string | null
  status: HookFireStatus
}

export interface HookFireStatsResponse {
  generatedAt: string
  path: string
  status: 'ok' | 'absent' | 'error'
  error?: string
  earliestObservedAt: string | null
  daysObserved: number
  modules: HookFireModuleRow[]
}
