// Shared types for the agent-test UI.
//
// SourceType-Mapping zur Methodik-Anzeige:
//   mc / regex          → "Machine-Check (deterministisch)"
//   kb_faq              → "Knowledge-Base (kuratiert)"
//   llm_local           → "Lokales LLM (qwen2.5:7b)"
//   llm_local_big       → "Externes LLM (OVH 120b)"
//   llm_cloud           → "Cloud-LLM (Claude, anonymisiert)"
//   cross               → "Cross-Doc-Vergleich"

export type Severity = 'HIGH' | 'MEDIUM' | 'LOW' | 'INFO'

// Verdikt eines Checks — getrennt vom Risiko (severity).
// Applicability ≠ Compliance · Unknown ≠ Fail.
export type CheckStatus =
  | 'pass'
  | 'fail'
  | 'not_applicable'
  | 'insufficient_evidence'
  | 'possibly_applicable'

export type SourceType =
  | 'mc'
  | 'regex'
  | 'kb_faq'
  | 'llm_local'
  | 'llm_local_big'
  | 'llm_cloud'
  | 'cross'

export interface EvidenceSource {
  source_type: SourceType
  source_id: string
  detail?: string
  confidence?: number
}

export interface Finding {
  check_id: string
  agent: string
  agent_version: string
  field_id?: string
  status?: CheckStatus
  severity: Severity
  severity_reason?: string
  title: string
  norm?: string
  evidence?: string
  action?: string
  confidence?: number
  sources?: EvidenceSource[]
}

export interface Recommendation {
  recommendation_id: string
  title: string
  body: string
  severity: Severity
  related_finding_ids: string[]
  estimated_effort_hours: number
}

export interface McCoverage {
  mc_id: string
  status: 'ok' | 'na' | 'high' | 'medium' | 'low' | 'skipped' |
    'insufficient_evidence' | 'possibly_applicable'
  reason?: string
  label?: string   // menschlicher Feldname (KEINE mc_id im Frontend zeigen)
  found?: string   // gefundener Text/Wert bei status=ok
}

export interface EscalationLog {
  stage: SourceType
  model: string
  duration_ms: number
  tokens_in?: number
  tokens_out?: number
  success: boolean
  error?: string
}

export interface SlotOutput {
  agent: string
  agent_version: string
  findings: Finding[]
  recommendations: Recommendation[]
  mc_coverage: McCoverage[]
  escalation_log: EscalationLog[]
  mc_total: number
  mc_ok: number
  mc_na: number
  mc_high: number
  mc_medium: number
  mc_low: number
  mc_insufficient?: number
  mc_possibly?: number
  duration_ms: number
  confidence: number
  notes?: string
}

export interface AgentInfo {
  agent_id: string
  agent_version: string
  doc_type: string
  mc_count: number
}

export interface RunResult {
  run_id: string
  agent_id: string
  finished: boolean
  results: Record<string, SlotOutput>
  vault_url: string
}

export interface StreamEvent {
  type: string
  slot?: string
  [key: string]: any
}

// ── Methodik-Labels für die Source-Type-Badge ───────────────────────

export const METHODIK_LABEL: Record<SourceType, string> = {
  mc: 'Machine-Check (deterministisch)',
  regex: 'Pattern-Match (deterministisch)',
  kb_faq: 'Knowledge-Base (kuratiert)',
  llm_local: 'Lokales LLM (qwen2.5:7b)',
  llm_local_big: 'Externes LLM (OVH 120b)',
  llm_cloud: 'Cloud-LLM (anonymisiert)',
  cross: 'Cross-Doc-Vergleich',
}

export const METHODIK_SHORT: Record<SourceType, string> = {
  mc: 'MC',
  regex: 'Regex',
  kb_faq: 'KB',
  llm_local: 'LLM',
  llm_local_big: 'LLM⁺',
  llm_cloud: 'Claude',
  cross: 'Cross',
}

// Background/foreground colors für die Methodik-Badge.
export const METHODIK_COLOR: Record<SourceType, { bg: string; fg: string }> = {
  mc:            { bg: '#e0e7ff', fg: '#3730a3' },
  regex:         { bg: '#e0e7ff', fg: '#3730a3' },
  kb_faq:        { bg: '#fef3c7', fg: '#92400e' },
  llm_local:     { bg: '#dcfce7', fg: '#166534' },
  llm_local_big: { bg: '#bbf7d0', fg: '#14532d' },
  llm_cloud:     { bg: '#fce7f3', fg: '#9d174d' },
  cross:         { bg: '#fed7aa', fg: '#9a3412' },
}

export const SEVERITY_COLOR: Record<Severity, string> = {
  HIGH: '#dc2626',
  MEDIUM: '#f59e0b',
  LOW: '#3b82f6',
  INFO: '#64748b',
}

export const SEVERITY_BG: Record<Severity, string> = {
  HIGH: '#fef2f2',
  MEDIUM: '#fffbeb',
  LOW: '#eff6ff',
  INFO: '#f8fafc',
}

// Verdikt-Pill — nur für die Nicht-FAIL-Status (FAIL trägt die Severity).
export const STATUS_LABEL: Partial<Record<CheckStatus, string>> = {
  not_applicable: 'Nicht anwendbar',
  insufficient_evidence: 'Unzureichende Evidenz',
  possibly_applicable: 'Evtl. relevant',
}

export const STATUS_STYLE: Partial<
  Record<CheckStatus, { bg: string; fg: string }>
> = {
  not_applicable: { bg: '#f1f5f9', fg: '#64748b' },
  insufficient_evidence: { bg: '#e2e8f0', fg: '#475569' },
  possibly_applicable: { bg: '#fef9c3', fg: '#854d0e' },
}

// Ein Output gilt als "übersprungen" (Dokument nicht ladbar), wenn MCs
// existieren, aber keiner ausgewertet wurde.
export function isOutputSkipped(o: SlotOutput): boolean {
  return o.mc_total > 0 && o.mc_ok === 0 && o.mc_na === 0 &&
    o.mc_high === 0 && o.mc_medium === 0 && o.mc_low === 0
}
