import { useEffect, useState } from 'react';
import { Trophy } from 'lucide-react';
import { ListContests, ContestStats } from '../../wailsjs/go/main/App';
import { cn } from '@/lib/utils';
import { useI18n } from '@/lib/i18n';

// ContestSession is the live contest-mode state, persisted as JSON in a UI pref
// so a running contest (serial counter included) survives a restart.
export type ContestSession = {
  active: boolean;
  code: string;       // ADIF CONTEST_ID written to each QSO
  name: string;
  exchange: 'serial' | 'fixed';
  fixedKind: string;  // label for the fixed exchange (CQ Zone, Département…)
  sentFixed: string;  // the value YOU send when the exchange is fixed
  nextSerial: number; // running sent serial number
  startISO: string;   // contest window start (UTC ISO) — only QSOs after count
  endISO: string;     // contest window end (UTC ISO, empty = open)
};

export const CONTEST_DEFAULT: ContestSession = {
  active: false, code: '', name: '', exchange: 'serial',
  fixedKind: 'CQ Zone', sentFixed: '', nextSerial: 1,
  startISO: '', endISO: '',
};

// Contests run on UTC, so the date/time inputs are treated as UTC.
const utcInputToISO = (v: string) => (v ? new Date(v + ':00Z').toISOString() : '');
const isoToUtcInput = (iso: string) => (iso ? new Date(iso).toISOString().slice(0, 16) : '');

const FIXED_KINDS = ['CQ Zone', 'ITU Zone', 'State/Prov', 'Département', 'Grid', 'Name', 'Age', 'Section', 'Custom'];
const KIND_LABEL: Record<string, string> = {
  'cq-zone': 'CQ Zone', 'itu-zone': 'ITU Zone', 'state': 'State/Prov',
  'dept': 'Département', 'grid': 'Grid', 'name': 'Name', 'class-section': 'Section',
};

type Def = { code: string; name: string; exchange: string };
type Stats = { qsos: number; by_band?: { band: string; count: number }[] | null; mult: number; mult_label: string; score: number; last_hour: number };

function Stat({ label, value, accent }: { label: string; value: string | number; accent?: string }) {
  return (
    <div className="rounded-lg border border-border bg-card px-3 py-2 text-center">
      <div className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground">{label}</div>
      <div className="text-xl font-black tabular-nums" style={accent ? { color: accent } : undefined}>{value}</div>
    </div>
  );
}

export function ContestPanel({ session, onChange }: {
  session: ContestSession;
  onChange: (patch: Partial<ContestSession>) => void;
}) {
  const { t } = useI18n();
  const [contests, setContests] = useState<Def[]>([]);
  const [stats, setStats] = useState<Stats | null>(null);

  useEffect(() => { ListContests().then((c) => setContests((c ?? []) as Def[])).catch(() => {}); }, []);

  // Poll the scoreboard while a contest is running.
  useEffect(() => {
    if (!session.active || !session.code) { setStats(null); return; }
    let alive = true;
    const load = () => ContestStats(
      session.code,
      session.exchange === 'fixed' ? kindKey(session.fixedKind) : 'serial',
      session.startISO, session.endISO,
    ).then((s) => { if (alive) setStats(s as Stats); }).catch(() => {});
    load();
    const id = window.setInterval(load, 4000);
    return () => { alive = false; window.clearInterval(id); };
  }, [session.active, session.code, session.exchange, session.fixedKind, session.startISO, session.endISO]);

  const pickContest = (code: string) => {
    const def = contests.find((c) => c.code === code);
    if (!def) { onChange({ code: '', name: '' }); return; }
    if (def.exchange === 'serial' || def.exchange === 'rst') {
      onChange({ code: def.code, name: def.name, exchange: 'serial' });
    } else {
      onChange({ code: def.code, name: def.name, exchange: 'fixed', fixedKind: KIND_LABEL[def.exchange] || 'Custom' });
    }
  };

  return (
    <div className="h-full overflow-y-auto p-4 space-y-4">
      {/* Setup card. */}
      <div className="rounded-xl border border-border bg-card shadow-sm overflow-hidden">
        <div className="flex items-center gap-2 px-4 py-2.5 border-b border-border/60 bg-muted/30">
          <Trophy className="size-4 text-warning" />
          <span className="text-xs font-bold uppercase tracking-wider text-foreground/80">{t('ctp.contestSetup')}</span>
          {session.active && <span className="ml-auto rounded bg-warning px-2 py-0.5 text-[10px] font-black uppercase tracking-wider text-warning-foreground">{t('ctp.live')}</span>}
        </div>
        <div className="p-4 space-y-3">
          <div className="flex flex-wrap items-center gap-2">
            <select value={session.code} onChange={(e) => pickContest(e.target.value)}
              className="rounded-md border border-border bg-card px-2 py-1.5 text-sm flex-1 min-w-[220px]">
              <option value="">{t('ctp.chooseContest')}</option>
              {contests.map((c) => <option key={c.code} value={c.code}>{c.name}</option>)}
            </select>
            {session.code && <code className="text-xs text-muted-foreground">{session.code}</code>}
          </div>

          <div className="flex flex-wrap items-center gap-3">
            <div className="inline-flex rounded-md border border-border overflow-hidden">
              {(['serial', 'fixed'] as const).map((x) => (
                <button key={x} type="button" onClick={() => onChange({ exchange: x })}
                  className={cn('px-3 py-1.5 text-xs font-bold border-l border-border first:border-l-0',
                    session.exchange === x ? 'bg-primary text-primary-foreground' : 'bg-card text-muted-foreground hover:bg-muted')}>
                  {x === 'serial' ? t('ctp.serial') : t('ctp.fixedExchange')}
                </button>
              ))}
            </div>

            {session.exchange === 'serial' ? (
              <label className="flex items-center gap-1.5 text-xs text-muted-foreground">
                {t('ctp.nextSerial')}
                <input type="number" min={1} value={session.nextSerial}
                  onChange={(e) => onChange({ nextSerial: Math.max(1, parseInt(e.target.value || '1', 10)) })}
                  className="w-20 rounded-md border border-border bg-card px-2 py-1.5 text-sm font-mono" />
              </label>
            ) : (
              <div className="flex items-center gap-2">
                <select value={session.fixedKind} onChange={(e) => onChange({ fixedKind: e.target.value })}
                  className="rounded-md border border-border bg-card px-2 py-1.5 text-sm">
                  {FIXED_KINDS.map((k) => <option key={k} value={k}>{k}</option>)}
                </select>
                <input value={session.sentFixed} onChange={(e) => onChange({ sentFixed: e.target.value.toUpperCase() })}
                  placeholder={t('ctp.yourExchangePh')} className="w-32 rounded-md border border-border bg-card px-2 py-1.5 text-sm font-mono" />
              </div>
            )}
          </div>

          {/* Contest window (UTC). Only QSOs inside it count toward the score and
              dupe check — so old runs of the same contest aren't included. */}
          <div className="flex flex-wrap items-center gap-3">
            <label className="flex items-center gap-1.5 text-xs text-muted-foreground">
              {t('ctp.startUtc')}
              <input type="datetime-local" value={isoToUtcInput(session.startISO)}
                onChange={(e) => onChange({ startISO: utcInputToISO(e.target.value) })}
                className="rounded-md border border-border bg-card px-2 py-1.5 text-sm" />
            </label>
            <label className="flex items-center gap-1.5 text-xs text-muted-foreground">
              {t('ctp.endUtc')}
              <input type="datetime-local" value={isoToUtcInput(session.endISO)}
                onChange={(e) => onChange({ endISO: utcInputToISO(e.target.value) })}
                className="rounded-md border border-border bg-card px-2 py-1.5 text-sm" />
            </label>
            <span className="text-[11px] text-muted-foreground">{t('ctp.windowHint')}</span>
          </div>

          <div className="flex items-center gap-2 pt-1">
            {session.active ? (
              <button type="button" onClick={() => onChange({ active: false })}
                className="rounded-md border border-danger/60 bg-danger/10 px-4 py-1.5 text-sm font-bold text-danger hover:bg-danger/20">
                {t('ctp.stopContest')}
              </button>
            ) : (
              <button type="button" disabled={!session.code}
                onClick={() => onChange({ active: true, startISO: session.startISO || new Date().toISOString() })}
                className="rounded-md bg-warning px-4 py-1.5 text-sm font-bold text-warning-foreground hover:bg-warning disabled:opacity-40">
                {t('ctp.startContest')}
              </button>
            )}
            <span className="text-xs text-muted-foreground">
              {session.active ? t('ctp.activeHint') : t('ctp.inactiveHint')}
            </span>
          </div>
        </div>
      </div>

      {/* Scoreboard. */}
      {session.active && (
        <div className="rounded-xl border border-border bg-card shadow-sm overflow-hidden">
          <div className="flex items-center gap-2 px-4 py-2.5 border-b border-border/60 bg-muted/30">
            <span className="text-xs font-bold uppercase tracking-wider text-foreground/80">{t('ctp.scoreboard')}</span>
            <span className="text-[10px] text-muted-foreground">{t('ctp.estimate')}</span>
          </div>
          <div className="p-4 space-y-4">
            <div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
              <Stat label={t('ctp.qsos')} value={stats?.qsos ?? 0} />
              <Stat label={stats?.mult_label || t('ctp.mult')} value={stats?.mult ?? 0} accent="#f59e0b" />
              <Stat label={t('ctp.scoreEst')} value={(stats?.score ?? 0).toLocaleString()} accent="#16a34a" />
              <Stat label={t('ctp.last60')} value={stats?.last_hour ?? 0} />
            </div>
            {stats && stats.by_band && stats.by_band.length > 0 && (
              <div className="rounded-lg border border-border overflow-hidden">
                <table className="w-full text-sm">
                  <thead><tr className="bg-muted/40 text-[11px] uppercase tracking-wider text-muted-foreground">
                    <th className="text-left px-3 py-1.5 font-bold">{t('ctp.band')}</th>
                    <th className="text-right px-3 py-1.5 font-bold">{t('ctp.qsos')}</th>
                  </tr></thead>
                  <tbody>
                    {stats.by_band.map((r) => (
                      <tr key={r.band} className="border-t border-border/60">
                        <td className="px-3 py-1 font-mono">{r.band}</td>
                        <td className="px-3 py-1 text-right tabular-nums">{r.count}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

// kindKey maps a fixed-kind label back to the backend's exchange key for mult
// counting.
function kindKey(label: string): string {
  const m: Record<string, string> = {
    'CQ Zone': 'cq-zone', 'ITU Zone': 'itu-zone', 'State/Prov': 'state',
    'Département': 'dept', 'Grid': 'grid', 'Name': 'name', 'Section': 'section', 'Age': 'age',
  };
  return m[label] || 'state';
}
