"use client";

import { useState, useRef, useCallback, useEffect } from "react";
import { useAnimation } from "framer-motion";
import confetti from "canvas-confetti";
import { requestJson } from "@/lib/fetcher";
import type { DrawnIdea } from "@/components/BlindboxDrawnHistory";
import type { RoomInfo } from "@/hooks/useBlindboxRoom";
import type { UserProfile } from "@/types";

type Phase = "pool" | "shaking" | "reveal" | "time_select" | "planning" | "plan_reveal";

export function useBlindboxDraw(
  room: RoomInfo | null,
  profile: UserProfile | null,
  poolCount: number,
  setPoolCount: React.Dispatch<React.SetStateAction<number>>,
  setDrawnHistory: React.Dispatch<React.SetStateAction<DrawnIdea[]>>,
  setError: (e: string) => void,
  setPhase: (p: Phase) => void,
) {
  const [revealedIdea, setRevealedIdea] = useState<DrawnIdea | null>(null);
  const [showShareCard, setShowShareCard] = useState(false);
  const boxControls = useAnimation();
  const confettiAliveRef = useRef(false);
  const timersRef = useRef<ReturnType<typeof setTimeout>[]>([]);
  const animationFrameRef = useRef<number | null>(null);

  const stopConfetti = useCallback(() => {
    confettiAliveRef.current = false;
    if (animationFrameRef.current !== null) {
      cancelAnimationFrame(animationFrameRef.current);
      animationFrameRef.current = null;
    }
    timersRef.current.forEach(clearTimeout);
    timersRef.current = [];
    if (typeof confetti.reset === "function") confetti.reset();
  }, []);

  const fireConfetti = useCallback(() => {
    stopConfetti();
    const colors = ["#a855f7", "#6366f1", "#ec4899", "#f59e0b", "#10b981"];
    confetti({ particleCount: 100, spread: 120, origin: { y: 0.4 }, colors, startVelocity: 45, ticks: 250 });
    confettiAliveRef.current = true;
    const end = Date.now() + 3000;
    const frame = () => {
      if (Date.now() > end || !confettiAliveRef.current) return;
      confetti({ particleCount: 3, angle: 60, spread: 55, origin: { x: 0, y: 0.6 }, colors, startVelocity: 35, ticks: 150 });
      confetti({ particleCount: 3, angle: 120, spread: 55, origin: { x: 1, y: 0.6 }, colors, startVelocity: 35, ticks: 150 });
      animationFrameRef.current = requestAnimationFrame(frame);
    };
    timersRef.current.push(
      setTimeout(() => {
        animationFrameRef.current = requestAnimationFrame(frame);
      }, 200),
    );
  }, [stopConfetti]);

  useEffect(
    () => () => {
      stopConfetti();
    },
    [stopConfetti],
  );

  const handleDraw = async () => {
    if (poolCount === 0 || !profile || !room) {
      setError("盒子是空的，先往里面塞点想法吧！");
      return;
    }

    setPhase("shaking");
    setError("");

    await boxControls.start({
      rotate: [0, -8, 8, -10, 10, -12, 12, -8, 8, -4, 4, 0],
      scale: [1, 1.05, 0.95, 1.08, 0.92, 1.1, 0.9, 1.05, 0.95, 1],
      transition: { duration: 2.5, ease: "easeInOut" },
    });

    try {
      const idea = await requestJson<DrawnIdea, { roomId: string }>("/api/blindbox/draw", {
        method: "POST",
        body: { roomId: room.id },
      });
      setRevealedIdea(idea);
      setPhase("reveal");
      setPoolCount((c) => Math.max(0, c - 1));
      setDrawnHistory((prev) => [idea, ...prev]);
      fireConfetti();
    } catch (e) {
      setError(e instanceof Error ? e.message : "抽取失败");
      setPhase("pool");
    }
  };

  const handleContinue = useCallback(() => {
    stopConfetti();
    setPhase("pool");
    setRevealedIdea(null);
    setShowShareCard(false);
  }, [setPhase, stopConfetti]);

  return {
    revealedIdea,
    showShareCard,
    setShowShareCard,
    boxControls,
    fireConfetti,
    handleDraw,
    handleContinue,
  };
}
