"use client";

import { useEffect, useRef, useState } from "react";
import { Avatar } from "@/components/avatar";
import { LaurelWreath } from "@/components/laurel-wreath";
import type { ProfileRow } from "./page";

const ITEM_WIDTH = 96;
const REPEATS = 6;
const SPIN_MS = 3200;

function useReducedMotion() {
  const [reduced, setReduced] = useState(
    () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches,
  );
  useEffect(() => {
    const query = window.matchMedia("(prefers-reduced-motion: reduce)");
    const handler = () => setReduced(query.matches);
    query.addEventListener("change", handler);
    return () => query.removeEventListener("change", handler);
  }, []);
  return reduced;
}

export function RouletteSection({ profiles }: { profiles: ProfileRow[] }) {
  const reducedMotion = useReducedMotion();
  const [citizensOnly, setCitizensOnly] = useState(false);
  const [spinning, setSpinning] = useState(false);
  const [strip, setStrip] = useState<ProfileRow[]>([]);
  const [offset, setOffset] = useState(0);
  const [transitionOn, setTransitionOn] = useState(false);
  const [winner, setWinner] = useState<ProfileRow | null>(null);
  const [lastWinner, setLastWinner] = useState<ProfileRow | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  const pool = citizensOnly ? profiles.filter((m) => m.role !== "judge") : profiles;

  function handleSpin() {
    if (spinning || pool.length === 0) return;

    const chosen = pool[Math.floor(Math.random() * pool.length)];

    if (reducedMotion) {
      setWinner(chosen);
      setLastWinner(chosen);
      return;
    }

    setWinner(null);
    setSpinning(true);

    const built: ProfileRow[] = [];
    for (let i = 0; i < REPEATS; i++) built.push(...pool);
    built.push(chosen);
    setStrip(built);
    setTransitionOn(false);
    setOffset(0);

    requestAnimationFrame(() => {
      const containerWidth = containerRef.current?.offsetWidth ?? 320;
      const finalIndex = built.length - 1;
      const target = finalIndex * ITEM_WIDTH + ITEM_WIDTH / 2 - containerWidth / 2;
      requestAnimationFrame(() => {
        setTransitionOn(true);
        setOffset(-target);
      });
    });
  }

  function handleTransitionEnd() {
    if (!spinning) return;
    setSpinning(false);
    const chosen = strip[strip.length - 1];
    setWinner(chosen);
    setLastWinner(chosen);
  }

  return (
    <div className="marble-surface rounded-2xl border border-gold/40 p-4 shadow-lg sm:p-6">
      <p className="text-center font-heading text-sm tracking-wide text-text-mut uppercase">La Roulette</p>
      <p className="mb-4 text-center font-serif text-xs text-text-mut/70 italic">Que le sort désigne l&apos;élu.</p>

      {profiles.length === 0 ? (
        <p className="text-center text-sm text-text-mut">Personne n&apos;est encore inscrit.</p>
      ) : (
        <>
          <label className="mb-4 flex items-center justify-center gap-2 text-sm text-text-marble">
            <input
              type="checkbox"
              checked={citizensOnly}
              onChange={(event) => setCitizensOnly(event.target.checked)}
              disabled={spinning}
              className="h-4 w-4 accent-gold"
            />
            Tirer uniquement parmi les Citoyens (exclure les Archontes)
          </label>

          <div
            ref={containerRef}
            className="relative isolate mx-auto mb-6 h-32 max-w-full overflow-hidden rounded-lg bg-ink-2/5"
          >
            <div
              className="absolute top-0 bottom-0 left-1/2 z-10 w-0.5 -translate-x-1/2 bg-gold-bright"
              aria-hidden
            />
            {strip.length > 0 && (
              <div
                className="flex h-full items-center"
                style={{
                  transform: `translateX(${offset}px)`,
                  transition: transitionOn ? `transform ${SPIN_MS}ms cubic-bezier(0.11, 0.7, 0.14, 1)` : "none",
                }}
                onTransitionEnd={handleTransitionEnd}
              >
                {strip.map((member, index) => (
                  <div
                    key={`${member.id}-${index}`}
                    className="flex shrink-0 flex-col items-center gap-1"
                    style={{ width: ITEM_WIDTH }}
                  >
                    <Avatar pseudo={member.pseudo} avatarUrl={member.avatar_url} size="md" />
                    <span className="max-w-[5rem] truncate text-xs text-text-marble">{member.pseudo}</span>
                  </div>
                ))}
              </div>
            )}
          </div>

          <div className="flex justify-center">
            <button
              type="button"
              onClick={handleSpin}
              disabled={spinning || pool.length === 0}
              className="rounded-md bg-ink-2 px-6 py-2.5 font-heading text-sm tracking-wide text-gold-bright uppercase transition hover:bg-ink disabled:opacity-50"
            >
              {spinning ? "…" : winner ? "Rejouer" : "Tirer au sort"}
            </button>
          </div>

          <div aria-live="polite" className="mt-8 flex flex-col items-center gap-2">
            {winner && (
              <div className="animate-reveal flex flex-col items-center gap-2 rounded-2xl px-8 py-6">
                <LaurelWreath className="h-10 w-10" color="#C9A227" />
                <div className="ring-4 ring-gold rounded-full p-1">
                  <Avatar pseudo={winner.pseudo} avatarUrl={winner.avatar_url} size="lg" />
                </div>
                <span className="font-heading text-2xl tracking-wide text-text-marble uppercase">
                  {winner.pseudo}
                </span>
                <span className="font-serif text-sm text-text-mut italic">a été désigné(e) par le sort</span>
              </div>
            )}
          </div>

          {lastWinner && !winner && (
            <p className="mt-4 text-center text-xs text-text-mut">
              Dernier élu : <span className="font-medium text-text-marble">{lastWinner.pseudo}</span>
            </p>
          )}
        </>
      )}
    </div>
  );
}
