'use client';

import { AnswerButton, CategoryChip, CountdownBar, LeaderboardList, type AnswerState } from '@/components/game';
import { CheckIcon, TrophyIcon } from '@/components/ui/icons';
import { cn } from '@/lib/cn';
import { useCountdown } from '@/lib/game';
import { formatPoints, secondsLeft } from '@/lib/play/format';
import { predictionsCloseAt } from '@/lib/play/screen';
import { Eyebrow, ScreenBody } from '../chrome';
import { letterFor } from '../parts';
import type { ActivePublic, PlayCtx } from '../types';

/** Finalists with their session points (finalists are the session's top five, so they're on the top-10 board). */
function finalistRows(pub: ActivePublic) {
  const finalists = pub.round.finalists ?? [];
  const points = new Map(pub.leaderboard.map((s) => [s.playerId, s] as const));
  return finalists
    .map((f) => ({ ...f, standing: points.get(f.playerId) ?? null }))
    .sort((a, b) => (a.standing?.rank ?? 99) - (b.standing?.rank ?? 99));
}

/** Non-finalists call the Final Rush winner (non-scoring) during INTRO / Q1 PENDING. */
export function PredictScreen({ ctx }: { ctx: PlayCtx }) {
  const pub = ctx.pub as ActivePublic;
  const me = ctx.me;
  const closesAt = predictionsCloseAt(pub.round, pub.question);
  const left = useCountdown(ctx.conn, closesAt, 250);
  const rows = finalistRows(pub);
  const shares = pub.predictions ?? {};
  return (
    <ScreenBody>
      <Eyebrow tone="amber">Final Rush</Eyebrow>
      <h1 className="mt-1 font-display text-[clamp(1.75rem,8vw,2.25rem)] leading-tight font-extrabold">Who takes the crown?</h1>
      <p className="mt-2 text-muted">The top five play five hard questions. Call the winner — just for bragging rights.</p>
      {closesAt !== null && (
        <p className="num mt-3 text-sm font-semibold text-amber-soft" role="timer" aria-live="off">
          Picks close in {secondsLeft(left)}s
        </p>
      )}
      <fieldset className="mt-5">
        <legend className="sr-only">Pick the Final Rush winner</legend>
        <ul className="flex flex-col gap-2.5">
          {rows.map((f) => {
            const chosen = me?.prediction === f.playerId;
            const share = shares[f.playerId] ?? 0;
            return (
              <li key={f.playerId}>
                <button
                  type="button"
                  aria-pressed={chosen}
                  onClick={() => void ctx.ctl.predict(f.playerId)}
                  className={cn(
                    'relative flex min-h-16 w-full items-center gap-3 overflow-hidden rounded-2xl border-2 px-4 py-2 text-left transition-[transform,border-color] duration-150 motion-safe:active:scale-[0.98]',
                    chosen ? 'border-amber bg-amber/15 shadow-glow-amber' : 'border-line-strong bg-raised hover:border-violet-soft',
                  )}
                >
                  <span aria-hidden="true" className="absolute inset-y-0 left-0 bg-amber/15" style={{ width: `${Math.round(share * 100)}%` }} />
                  <span className="relative grid size-9 shrink-0 place-items-center rounded-lg bg-white/10 font-display font-bold">
                    {chosen ? <CheckIcon className="size-5 text-amber" strokeWidth={3} /> : (f.standing?.rank ?? '–')}
                  </span>
                  <span className="relative min-w-0 flex-1">
                    <span className="block truncate font-semibold">{f.nickname}</span>
                    <span className="num block text-xs text-muted">{f.standing ? `${formatPoints(f.standing.points)} pts` : 'Finalist'}</span>
                  </span>
                  <span className="num relative text-sm font-bold text-muted">{Math.round(share * 100)}%</span>
                  <span className="sr-only">{chosen ? ', your pick' : ''}</span>
                </button>
              </li>
            );
          })}
        </ul>
      </fieldset>
      <p className="mt-4 text-center text-sm text-subtle">
        {me?.prediction ? 'Locked in — you can still change it until the first question opens.' : 'Tap a finalist to make your pick.'}
      </p>
    </ScreenBody>
  );
}

/** After predictions close: follow the finalists' race and the questions they face. */
export function WatchScreen({ ctx }: { ctx: PlayCtx }) {
  const pub = ctx.pub as ActivePublic;
  const me = ctx.me;
  const q = pub.question;
  const reveal = pub.reveal;
  const rows = finalistRows(pub);
  const myPick = me?.prediction ?? null;
  const total = q?.closesAt && q.openedAt ? q.closesAt - q.openedAt : 20_000;
  return (
    <ScreenBody>
      <Eyebrow tone="amber">Final Rush · watching</Eyebrow>
      <h1 className="mt-1 font-display text-2xl leading-tight font-extrabold">
        {pub.round.phase === 'ROUND_OVER'
          ? 'The final is over'
          : q
            ? `Question ${q.index + 1} of ${pub.round.questionCount}`
            : 'The finalists get ready'}
      </h1>
      {q && (
        <div className="mt-4 rounded-2xl border border-line bg-surface/80 p-4">
          <CategoryChip category={q.category} label={q.categoryLabel} size="sm" />
          {q.prompt ? (
            <>
              {pub.round.phase === 'OPEN' && (
                <CountdownBar conn={ctx.conn} endsAt={q.closesAt} totalMs={total} label="Time left for the finalists" className="mt-3" />
              )}
              <p className="mt-3 font-display text-lg leading-snug font-semibold">{q.prompt}</p>
              {q.options && (
                <div className="mt-3 flex flex-col gap-2">
                  {q.options.map((o, i) => {
                    const state: AnswerState = reveal ? (o.id === reveal.correctOptionId ? 'correct' : 'faded') : 'idle';
                    return <AnswerButton key={o.id} static letter={letterFor(i)} text={o.text} state={state} className="min-h-12 text-sm" />;
                  })}
                </div>
              )}
              {pub.round.phase === 'OPEN' && (
                <p className="num mt-2 text-sm text-subtle">
                  {pub.answeredCount} of {pub.participantCount} finalists answered
                </p>
              )}
            </>
          ) : (
            <p className="mt-3 text-muted">Up next for the finalists…</p>
          )}
        </div>
      )}
      <section className="mt-6" aria-labelledby="race">
        <h2 id="race" className="mb-2 flex items-center gap-2 text-xs font-bold tracking-[0.14em] text-subtle uppercase">
          <TrophyIcon className="size-4 text-amber" /> The race
        </h2>
        <LeaderboardList
          label="Finalists by points"
          rows={rows.map((f, i) => ({
            key: f.playerId,
            rank: i + 1,
            name: f.nickname,
            score: f.standing ? formatPoints(f.standing.points) : '—',
            highlight: f.playerId === myPick,
            badge:
              f.playerId === myPick ? (
                <span className="shrink-0 rounded-full bg-amber px-2 py-0.5 text-[0.625rem] font-extrabold tracking-[0.08em] text-on-bright uppercase">
                  Your pick
                </span>
              ) : undefined,
          }))}
        />
        {!myPick && <p className="mt-2 text-center text-sm text-subtle">You didn’t make a pick this time.</p>}
      </section>
    </ScreenBody>
  );
}
