'use client';

import { useEffect, useState } from 'react';

/**
 * AccuracyBadge (Session 55) — the self-learning loop made visible.
 *
 * Reads the rolling accuracy record (`/api/accuracy`, written by outcomeService
 * from settled grades vs REAL results) and renders the system's track record.
 * This is the #1 trust builder: a system that shows its hit rate, including its
 * misses. Honest by construction — below MIN_SAMPLE it reads "LEARNING" rather
 * than faking a number. All data (%) is mono per the brand rule; never glitches.
 */

interface Bucket { hits: number; misses: number; pushes: number; total: number; pct: number | null }
interface AccuracyRecord {
  window_days?: number;
  overall?: Bucket;
  byGrade?: Record<string, Bucket>;
}
interface AccuracyResponse {
  overall?: AccuracyRecord | null;
  min_sample?: number;
}

const BLANK: Bucket = { hits: 0, misses: 0, pushes: 0, total: 0, pct: null };

function merge(a?: Bucket, b?: Bucket): Bucket {
  const x = a || BLANK, y = b || BLANK;
  const hits = x.hits + y.hits, misses = x.misses + y.misses, pushes = x.pushes + y.pushes;
  const decided = hits + misses;
  return { hits, misses, pushes, total: hits + misses + pushes, pct: decided > 0 ? Math.round((hits / decided) * 100) : null };
}

type Variant = 'inline' | 'chip';

export default function AccuracyBadge({ variant = 'chip', sport }: { variant?: Variant; sport?: string }) {
  const [rec, setRec] = useState<AccuracyRecord | null>(null);
  const [minSample, setMinSample] = useState(8);
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    let active = true;
    fetch('/api/accuracy', { cache: 'no-store' })
      .then((r) => (r.ok ? r.json() : null))
      .then((data: AccuracyResponse | null) => {
        if (!active) return;
        setMinSample(data?.min_sample ?? 8);
        // Prefer a specific sport's record when asked; else the overall.
        const sportRec = sport && data && (data as unknown as { sports?: Record<string, AccuracyRecord> }).sports?.[sport];
        setRec((sportRec as AccuracyRecord) || data?.overall || null);
        setLoaded(true);
      })
      .catch(() => { if (active) setLoaded(true); });
    return () => { active = false; };
  }, [sport]);

  if (!loaded || !rec) return null;

  const aRated = merge(rec.byGrade?.['A+'], rec.byGrade?.['A']);
  const overall = rec.overall || BLANK;
  const window = rec.window_days || 30;

  // Honest states: A-rated record → overall record → "LEARNING".
  let label: string;
  let value: string;
  let color: string;
  let calibrated = true;
  if (aRated.hits + aRated.misses >= minSample && aRated.pct != null) {
    label = 'A-RATED'; value = `${aRated.pct}% HIT`; color = 'var(--g-a, #00D4A0)';
  } else if (overall.hits + overall.misses >= minSample && overall.pct != null) {
    label = 'MODEL'; value = `${overall.pct}% HIT`; color = 'var(--g-a, #00D4A0)';
  } else {
    label = 'MODEL'; value = 'LEARNING'; color = 'var(--amber, #FFB347)'; calibrated = false;
  }

  const title = calibrated
    ? `VYNDR's ${label === 'A-RATED' ? 'A-rated props' : 'graded props'} over the last ${window} days — including misses. The system settles every grade against real results.`
    : 'The self-learning loop is still collecting settled results. Hit rate appears once the sample is large enough to be honest.';

  if (variant === 'inline') {
    return (
      <span className="mono" title={title} style={{ fontSize: 11, letterSpacing: '0.06em', color }}>
        {label} · {value} {calibrated ? `· ${window}D` : ''}
      </span>
    );
  }

  return (
    <div
      className="mono"
      title={title}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        padding: '8px 14px', borderRadius: 999,
        background: 'var(--bg-surface, #12121A)',
        border: `1px solid ${color}`,
        fontSize: 12, color,
        letterSpacing: '0.06em', whiteSpace: 'nowrap',
      }}
    >
      <span
        aria-hidden
        style={{
          width: 7, height: 7, borderRadius: '50%', background: color,
          boxShadow: `0 0 6px ${color}`,
          animation: calibrated ? undefined : 'none',
        }}
      />
      <span style={{ fontWeight: 700 }}>{label}</span>
      <span style={{ color: 'var(--text-1, #B8BCC8)' }}>·</span>
      <span>{value}</span>
      {calibrated && <><span style={{ color: 'var(--text-2, #707080)' }}>·</span><span style={{ color: 'var(--text-2, #707080)' }}>{window}D</span></>}
    </div>
  );
}
