"use client";

import { useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { ListChecks, Sparkles } from "lucide-react";
import { gsap } from "@/lib/gsap";
import { celebrateConfetti } from "@/lib/confetti";
import { useSound } from "@/components/providers/sound-provider";
import { useLocalStorage } from "@/hooks/use-local-storage";
import { usePrefersReducedMotion } from "@/hooks/use-prefers-reduced-motion";

const DEFAULT_LIST = "Anna\nBen\nClara\nDavid";

export default function ListPicker() {
  const [text, setText] = useLocalStorage("list-items", DEFAULT_LIST);
  const [removeAfterDraw, setRemoveAfterDraw] = useLocalStorage(
    "list-remove",
    false,
  );
  const [display, setDisplay] = useState<string | null>(null);
  const [drawing, setDrawing] = useState(false);
  const [winner, setWinner] = useState<string | null>(null);

  const lastPaintRef = useRef(0);
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const { play } = useSound();
  const reduced = usePrefersReducedMotion();

  const items = text
    .split("\n")
    .map((s) => s.trim())
    .filter(Boolean);

  const insufficientItems = items.length < 2;

  const draw = () => {
    if (drawing) return;
    if (insufficientItems) {
      setDisplay(null);
      setWinner(null);
      play("tick");
      gsap.fromTo(
        textareaRef.current,
        { x: -7 },
        { x: 0, duration: 0.4, ease: "elastic.out(2.5, 0.35)" },
      );
      return;
    }

    const pick = items[Math.floor(Math.random() * items.length)];
    setDrawing(true);
    setWinner(null);
    play("whoosh");

    const dur = reduced ? 0.35 : 2.0;
    const proxy = { p: 0 };
    lastPaintRef.current = 0;

    gsap.to(proxy, {
      p: 1,
      duration: dur,
      ease: "power2.out",
      onUpdate: () => {
        const now = performance.now();
        const interval = reduced ? 60 : 30 + 260 * proxy.p;
        if (now - lastPaintRef.current > interval) {
          lastPaintRef.current = now;
          setDisplay(items[Math.floor(Math.random() * items.length)]);
        }
      },
      onComplete: () => {
        setDisplay(pick);
        setWinner(pick);
        setDrawing(false);
        play("win");
        celebrateConfetti();
        if (removeAfterDraw) {
          setText((prevText) => {
            const currentItems = prevText
              .split("\n")
              .map((s) => s.trim())
              .filter(Boolean);
            const idx = currentItems.indexOf(pick);
            if (idx === -1) return prevText;
            currentItems.splice(idx, 1);
            return currentItems.join("\n");
          });
        }
      },
    });
  };

  return (
    <div className="grid items-center gap-10 lg:grid-cols-[0.9fr_1.1fr]">
      {/* Liste */}
      <div className="rounded-3xl border border-line bg-cream/70 p-5">
        <h3 className="text-sm font-semibold uppercase tracking-[0.16em] text-ink-soft">
          Deine Liste ({items.length})
        </h3>
        <textarea
          ref={textareaRef}
          value={text}
          onChange={(e) => setText(e.target.value)}
          disabled={drawing}
          rows={8}
          placeholder={"Ein Eintrag pro Zeile, z. B.\nAnna\nBen\nClara"}
          aria-label="Liste der Einträge, ein Eintrag pro Zeile"
          className={`mt-4 w-full resize-none rounded-xl border bg-surface px-4 py-3 font-mono text-sm leading-relaxed outline-none transition focus:ring-2 disabled:cursor-not-allowed disabled:opacity-60 ${
            insufficientItems
              ? "border-clay/60 focus:border-clay/60 focus:ring-clay/20"
              : "border-line focus:border-primary/60 focus:ring-primary/20"
          }`}
        />
        <label className="mt-3 flex cursor-pointer items-center gap-2.5 text-sm font-medium text-ink-soft">
          <input
            type="checkbox"
            checked={removeAfterDraw}
            onChange={(e) => setRemoveAfterDraw(e.target.checked)}
            disabled={drawing}
            className="h-4 w-4 cursor-pointer accent-primary disabled:cursor-not-allowed"
          />
          Gezogene Einträge entfernen (ohne Zurücklegen)
        </label>
        <p className={`mt-3 text-xs leading-relaxed ${insufficientItems ? "font-semibold text-clay" : "text-ink-soft"}`}>
          {insufficientItems
            ? "Bitte mindestens 2 Einträge eintragen."
            : "Ideal für Teams, Gruppen-Reihenfolgen oder Gewinnspiele."}
        </p>
      </div>

      {/* Anzeige */}
      <div className="flex flex-col items-center">
        <div className="flex min-h-[190px] w-full items-center justify-center rounded-[2rem] border border-line bg-cream/70 px-8 py-8">
          <AnimatePresence mode="wait">
            {display === null ? (
              <motion.div
                key="idle"
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                className="flex flex-col items-center gap-3 text-center"
              >
                <ListChecks className="h-8 w-8 text-primary/50" />
                <p className="font-display text-xl font-medium text-ink-soft">
                  {!insufficientItems
                    ? `${items.length} Einträge warten auf die Ziehung.`
                    : "Trage links mindestens 2 Einträge ein."}
                </p>
              </motion.div>
            ) : (
              <motion.p
                key={display + (winner ? "-win" : "")}
                initial={winner ? { scale: 0.6, opacity: 0, y: 14 } : false}
                animate={{ scale: 1, opacity: 1, y: 0 }}
                transition={{ type: "spring", stiffness: 340, damping: 20 }}
                className={`break-words text-center font-display text-5xl font-semibold tracking-tight sm:text-6xl ${
                  winner ? "text-primary" : "text-ink/60"
                }`}
                aria-live="polite"
              >
                {display}
              </motion.p>
            )}
          </AnimatePresence>
        </div>

        <motion.button
          type="button"
          onClick={draw}
          disabled={drawing}
          whileTap={{ scale: 0.95 }}
          className="mt-6 inline-flex cursor-pointer items-center gap-2 rounded-full bg-primary px-9 py-3.5 text-base font-semibold text-white shadow-cta transition-colors duration-200 hover:bg-primary-strong disabled:cursor-not-allowed disabled:opacity-60"
        >
          <Sparkles className="h-5 w-5" />
          {drawing ? "Zieht …" : "Zufällig ziehen"}
        </motion.button>
        {winner && (
          <p className="mt-3 text-xs text-ink-soft">
            {removeAfterDraw
              ? `„${winner}“ wurde von der Liste entfernt.`
              : "Nochmal ziehen? Einfach erneut klicken."}
          </p>
        )}
      </div>
    </div>
  );
}
