'use client';

import type { PublicState } from '@pintrush/engine';
import { LockIcon } from '@/components/ui/icons';
import { cn } from '@/lib/cn';
import { optionLetter } from '@/lib/tv/format';
import { optionFontSize, promptFontSize } from '@/lib/tv/results';
import { lateJoinOpen } from '@/lib/tv/screen';
import { cssVars } from '../cssVars';
import { CountdownRing } from '../parts/Countdown';
import { CornerJoin } from '../parts/JoinQr';
import { TopBar } from '../parts/TopBar';
import s from '../tv.module.css';

/** Category / difficulty / wildcard chips shown above the prompt. */
export function QuestionChips({ q, kind }: { q: NonNullable<PublicState['question']>; kind: NonNullable<PublicState['round']>['kind'] }) {
  return (
    <div className="flex flex-wrap items-center gap-[14px]">
      <span className="rounded-full border border-cyan/45 bg-cyan/12 px-[22px] py-[8px] text-[24px] font-bold tracking-[0.16em] text-cyan-soft uppercase">{q.categoryLabel}</span>
      {q.isWildcard && <span className="rounded-full bg-lime px-[22px] py-[8px] text-[24px] font-extrabold tracking-[0.12em] text-on-bright uppercase">Wildcard</span>}
      {q.difficulty === 'DIFFICULT' && (
        <span className="rounded-full border border-amber/50 bg-amber/12 px-[22px] py-[8px] text-[24px] font-bold tracking-[0.12em] text-amber-soft uppercase">Difficult · 150</span>
      )}
      {kind === 'TABLE_WARS' && <span className="rounded-full border border-violet/50 bg-violet/15 px-[22px] py-[8px] text-[24px] font-bold tracking-[0.12em] text-violet-soft uppercase">Table challenge</span>}
      {kind === 'FINAL_RUSH' && <span className="rounded-full border border-amber/50 bg-amber/12 px-[22px] py-[8px] text-[24px] font-bold tracking-[0.12em] text-amber-soft uppercase">Finalists only</span>}
    </div>
  );
}

/** Live "N of M answered" meter (never says who answered what). */
export function AnsweredMeter({ answered, total, locked }: { answered: number; total: number; locked: boolean }) {
  const ratio = total > 0 ? Math.min(1, answered / total) : 0;
  return (
    <div className="flex items-center gap-[28px]">
      {locked && (
        <p className={cn('shrink-0 rounded-full bg-violet-deep px-[28px] py-[8px] font-display text-[28px] font-extrabold tracking-[0.12em] text-white uppercase shadow-glow-violet', s.chipIn)}>
          Answers locked
        </p>
      )}
      <p className="num shrink-0 text-[34px] font-semibold text-muted">
        <span className="font-display font-bold text-fg">{answered}</span> of {total} answered
      </p>
      <div aria-hidden="true" className="h-[14px] flex-1 overflow-hidden rounded-full bg-line/70">
        <div
          className={cn('h-full origin-left rounded-full transition-transform duration-500 ease-out', locked ? 'bg-line-strong' : 'bg-[linear-gradient(90deg,var(--color-violet),var(--color-cyan))]')}
          style={{ transform: `scaleX(${ratio})` }}
        />
      </div>
    </div>
  );
}

function LockBadge() {
  return (
    <div className={cn('relative grid size-[280px] shrink-0 place-items-center', s.lockBeat)}>
      <span aria-hidden="true" className="absolute inset-0 rounded-full border-[10px] border-violet-soft/70 bg-violet/20 shadow-glow-violet" />
      <span className="relative flex flex-col items-center gap-[8px] text-violet-soft">
        <LockIcon className="size-[104px]" />
        <span className="font-display text-[30px] font-extrabold tracking-[0.2em] uppercase">Locked</span>
      </span>
    </div>
  );
}

/**
 * OPEN and LOCKED: the prompt, four options, the countdown ring and the answered meter. LOCKED keeps
 * the same layout (same React node) and swaps the ring for a lock beat, so the moment reads clearly
 * from across the room. Nothing here can show the answer: the public state has none before reveal.
 */
export function QuestionScreen({ pub, locked }: { pub: PublicState; locked: boolean }) {
  const q = pub.question;
  const round = pub.round;
  if (!q || !round || !q.prompt || !q.options) return null;
  const options = q.options;
  const twoUp = options.length <= 2;
  // Kept through LOCKED too, so the prompt never reflows at the lock beat.
  const showJoin = lateJoinOpen(round);
  // Stage budget: 1920 − 2×72 padding − 280 ring − 56 gap (− 202 corner QR − 56 gap); 370 px tall below the chips.
  const fontSize = promptFontSize(q.prompt, { width: showJoin ? 1182 : 1440, height: 370 });
  const optionSize = optionFontSize(options);

  return (
    <div className="absolute inset-0 flex flex-col px-[72px] pt-[48px] pb-[48px]">
      <TopBar pub={pub} />
      <div className="mt-[36px] flex min-h-[300px] items-center gap-[56px]">
        {locked || q.openedAt === null || q.closesAt === null ? <LockBadge /> : <CountdownRing openedAt={q.openedAt} closesAt={q.closesAt} size={280} />}
        <div className="flex min-w-0 flex-1 flex-col gap-[22px]">
          <QuestionChips q={q} kind={round.kind} />
          <h1 className="font-display leading-[1.1] font-bold tracking-[-0.025em] text-balance" style={{ fontSize }}>
            {q.prompt}
          </h1>
        </div>
        {showJoin && <CornerJoin />}
      </div>

      <ul className={cn('mt-auto grid gap-[24px]', twoUp ? 'grid-cols-2' : 'grid-cols-2 grid-rows-2')}>
        {options.map((o, i) => (
          <li
            key={o.id}
            className={cn(
              'flex items-center gap-[28px] rounded-[28px] border-2 px-[30px] transition-[opacity,border-color,background-color] duration-500',
              twoUp ? 'h-[190px]' : 'h-[150px]',
              locked ? 'border-line bg-raised/40 opacity-60' : 'border-line-strong/70 bg-raised/75',
              s.chipIn,
            )}
            style={cssVars({ '--delay': `${i * 80}ms` })}
          >
            <span className="grid size-[88px] shrink-0 place-items-center rounded-[22px] bg-violet/30 font-display text-[46px] font-extrabold text-violet-soft">{optionLetter(i)}</span>
            <span className="line-clamp-2 min-w-0 leading-[1.12] font-semibold" style={{ fontSize: optionSize }}>
              {o.text}
            </span>
          </li>
        ))}
      </ul>

      <div className="mt-[30px]">
        <AnsweredMeter answered={pub.answeredCount} total={pub.participantCount} locked={locked} />
      </div>

      {locked && <div aria-hidden="true" className={cn('pointer-events-none absolute inset-0 bg-violet/25', s.flash)} />}
    </div>
  );
}
