// === Metric tiers ===
// wer_raw:      minimal normalization, strict fidelity
// wer_norm:     PRIMARY metric — NFKC + whitespace + punctuation + case fold
// wer_numcanon: wer_norm + number canonicalization
// cer_norm:     character-level normalized — critical for Indic scripts

export interface NormalizationDelta {
  raw_to_norm: number;       // wer_raw - wer_norm (negative = norm helped)
  norm_to_numcanon: number;  // wer_norm - wer_numcanon
  norm_to_mer?: number;      // wer_norm - mer (quantifies spacing error inflation)
}

export interface LanguageMetrics {
  n_samples: number;
  wer_raw: number;
  wer_norm: number;
  wer_numcanon: number;
  mer: number;
  cer_norm: number;
  space_norm_wer?: number;
  wer_norm_nonum?: number;
  mer_nonum?: number;
  numeric_samples_dropped?: number;
  empty_hypotheses: number;
  normalization_delta: NormalizationDelta;
}

export interface AggregateMetrics {
  n_samples: number;
  wer_raw: number;
  wer_norm: number;
  wer_numcanon: number;
  mer: number;
  cer_norm: number;
  space_norm_wer?: number;
  wer_norm_nonum?: number;
  mer_nonum?: number;
  numeric_samples_dropped?: number;
}

export interface MacroAvgMetrics {
  n_languages: number;
  wer_raw: number;
  wer_norm: number;
  wer_numcanon: number;
  mer: number;
  cer_norm: number;
}

export interface MetaMeta {
  checkpoint: string;
  checkpoint_name: string;
  model_id: string;
  model_type?: string;
  dataset: string;
  batch_size?: number;
  force_language?: boolean;
  inference_time_sec: number;
  total_audio_sec: number;
  rtf: number;
  timestamp?: string;
  gpu?: string;
  framework?: string;
  normalization_version?: string;
  jiwer_version?: string;
}

export type MetricsFile = {
  [language: string]: LanguageMetrics | AggregateMetrics | MacroAvgMetrics | MetaMeta;
} & {
  __overall__: AggregateMetrics;
  __macro_avg__: MacroAvgMetrics;
  __meta__: MetaMeta;
};

export interface SampleAnalysis {
  id: string;
  language: string;
  reference: string;
  hypothesis: string;
  ref_norm?: string;
  hyp_norm?: string;
  ref_numcanon?: string;
  hyp_numcanon?: string;
  detected_language?: string;
  wer_raw?: number;
  wer_norm?: number;
  flags?: string[];
}

export interface ErrorBuckets {
  numeric_mismatch_count: number;
  punctuation_only_count: number;
  spacing_tokenization_count: number;
  entity_mismatch_count: number;
  script_confusion_count: number;
  empty_hypothesis_count: number;
}

export interface SubstitutionEntry {
  ref: string;
  hyp: string;
  count: number;
}

export interface WordCountEntry {
  word: string;
  count: number;
}

export interface LanguageErrorAnalysis {
  top_substitutions: SubstitutionEntry[];
  top_insertions: WordCountEntry[];
  top_deletions: WordCountEntry[];
  error_buckets: ErrorBuckets;
  examples: {
    worst_samples: string[];
    best_samples: string[];
    numeric_mismatch_samples: string[];
    entity_mismatch_samples: string[];
  };
}

export interface ErrorAnalysisSummary {
  model_diagnosis: "recognition-limited" | "formatting-limited" | "numeric-limited" | "mixed";
  primary_error_source: string;
  numeric_verbalization_impact: string;
  formatting_impact: string;
  worst_languages: string[];
  best_languages: string[];
}

export type ErrorAnalysisFile = {
  [language: string]: LanguageErrorAnalysis | ErrorAnalysisSummary;
} & {
  __summary__: ErrorAnalysisSummary;
};

export interface ModelInfo {
  id: string;
  displayName: string;
  checkpoints: string[];
}

export interface CheckpointComparison {
  language: string;
  [key: string]: number | string;
}

// === Constants ===

export const MODEL_REGISTRY: Record<string, string> = {
  "qwen3-asr": "Qwen3-ASR-1.7B",
  "gemma3n-e2b": "Gemma-3n-E2B-ASR",
  "parakeet-1.1b": "Parakeet-1.1B-Language-Guided",
  "parakeet-tdt-1.1b-lang": "Parakeet-TDT-1.1B-Lang",
  "qwen3-asr-mixed": "Qwen3-ASR-Mixed-v1",
  "qwen3-asr-mixed-v2": "Qwen3-ASR-Mixed-v2",
  "cohere-transcribe": "Cohere-Transcribe",
  "elevenlabs-scribe-v2": "ElevenLabs Scribe v2",
  "elevenlabs-scribe-v1": "ElevenLabs Scribe v1",
  "gemini-3-flash-strict": "Gemini 3 Flash (Strict)",
  "gemini-3.1-pro": "Gemini 3.1 Pro",
  "sarvam-saaras-v3": "Sarvam Saaras v3",
};

// Models grouped by category
export const OUR_MODELS = ["qwen3-asr", "qwen3-asr-mixed", "qwen3-asr-mixed-v2", "gemma3n-e2b", "parakeet-1.1b", "parakeet-tdt-1.1b-lang", "cohere-transcribe"] as const;
export const BASELINE_MODELS = [
  "elevenlabs-scribe-v2", "elevenlabs-scribe-v1",
  "gemini-3-flash-strict", "gemini-3.1-pro",
  "sarvam-saaras-v3",
] as const;

export const LANGUAGES = [
  "assamese", "bengali", "english", "gujarati", "hindi", "kannada",
  "malayalam", "marathi", "odia", "punjabi", "tamil", "telugu",
] as const;

export const LANGUAGE_CODES: Record<string, string> = {
  assamese: "as", bengali: "bn", english: "en", gujarati: "gu",
  hindi: "hi", kannada: "kn", malayalam: "ml", marathi: "mr",
  odia: "or", punjabi: "pa", tamil: "ta", telugu: "te",
};

export const METRIC_TIERS = ["wer_raw", "wer_norm", "wer_numcanon", "space_norm_wer", "mer", "cer_norm", "wer_norm_nonum", "mer_nonum"] as const;
export type MetricTier = typeof METRIC_TIERS[number];

export const METRIC_LABELS: Record<MetricTier, string> = {
  wer_raw: "WER Raw",
  wer_norm: "WER Norm",
  wer_numcanon: "WER NumCanon",
  space_norm_wer: "Space-Norm WER",
  mer: "MER",
  cer_norm: "CER Norm",
  wer_norm_nonum: "WER (no num)",
  mer_nonum: "MER (no num)",
};

export const METRIC_DESCRIPTIONS: Record<MetricTier, string> = {
  wer_raw: "Strict transcript fidelity",
  wer_norm: "Primary ASR metric",
  wer_numcanon: "Numeric robustness",
  space_norm_wer: "Word-level errors after space-insensitive char alignment",
  mer: "Meaningful Error Rate (space-normalized)",
  cer_norm: "Script-sensitive (Indic)",
  wer_norm_nonum: "WER excluding numeric samples",
  mer_nonum: "MER excluding numeric samples",
};

// Primary tiers shown in the main metric selector (exclude nonum variants)
export const PRIMARY_METRIC_TIERS = ["wer_raw", "wer_norm", "wer_numcanon", "space_norm_wer", "mer", "cer_norm"] as const;

export const CHART_COLORS = [
  "#6366f1", "#8b5cf6", "#a78bfa", "#c084fc",
  "#e879f9", "#f472b6", "#fb7185", "#f87171",
  "#fb923c", "#fbbf24", "#a3e635", "#34d399",
];

export const MODEL_COLORS: Record<string, string> = {
  "qwen3-asr": "#6366f1",
  "gemma3n-e2b": "#8b5cf6",
  "parakeet-1.1b": "#34d399",
  "parakeet-tdt-1.1b-lang": "#2dd4bf",
  "qwen3-asr-mixed": "#818cf8",
  "qwen3-asr-mixed-v2": "#c084fc",
  "cohere-transcribe": "#f59e0b",
  "elevenlabs-scribe-v2": "#f472b6",
  "elevenlabs-scribe-v1": "#fb7185",
  "gemini-3-flash-strict": "#fbbf24",
  "gemini-3.1-pro": "#a3e635",
  "sarvam-saaras-v3": "#22d3ee",
};

// === Backward compatibility ===
// Converts old-schema metrics into new-schema shape so dashboard works
// with both old data (pre-migration) and new data.

export interface OldLanguageMetrics {
  n_samples: number;
  wer: number;
  cer: number;
  wer_normalized: number;
  cer_normalized: number;
  empty_hypotheses: number;
}

export function isOldSchema(obj: Record<string, unknown>): boolean {
  return "wer" in obj && !("wer_raw" in obj);
}

export function migrateLanguageMetrics(old: OldLanguageMetrics): LanguageMetrics {
  return {
    n_samples: old.n_samples,
    wer_raw: old.wer,
    wer_norm: old.wer_normalized,
    wer_numcanon: old.wer_normalized,
    mer: old.cer_normalized, // fallback: use CER as rough MER proxy
    cer_norm: old.cer_normalized,
    empty_hypotheses: old.empty_hypotheses,
    normalization_delta: {
      raw_to_norm: old.wer - old.wer_normalized,
      norm_to_numcanon: 0,
      norm_to_mer: 0,
    },
  };
}
