import { useCallback, useEffect, useRef, useState } from "react";

// 페이지 맨 위 파도타기 — 5마리가 순차로 만세(팔 올림)했다 내린다.
// 5마리는 한 그룹으로 묶여 함께 끌어 옮길 수 있고, 각 캐릭터를 탭하면
// 남아공전 응원 말풍선이 뜬다.
type Animal = { name: string; lines: string[] };

const WAVE: Animal[] = [
  {
    name: "bull",
    lines: [
      "한국, 남아공 잡고 16강 가자! 🇰🇷",
      "남아공 수비를 뚫어라! 🐂",
      "오늘 이기면 16강이 보인다",
      "대~한민국! 짝짝짝 👏",
      "투우사도 한국 응원한다 ⚽",
      "스페인도 한국 편이다 🇪🇸",
      "남아공 골키퍼 긴장해라!",
      "한 골이 16강을 가른다",
      "투지로 밀어붙여! 💪",
      "끝까지 간다, 대한민국!",
    ],
  },
  {
    name: "eagle",
    lines: [
      "남아공전 무조건 이긴다 🦅",
      "한국 16강 가즈아 🇰🇷",
      "남아공 골문을 노려라!",
      "이 경기 잡으면 토너먼트행 ✈️",
      "골! 골! 대한민국! ⚽",
      "아르헨도 한국 편 🇦🇷",
      "역습 한 방이면 끝난다",
      "오늘 클린시트 가자 🧤",
      "남아공 수비 흔들어!",
      "16강에서 또 보자 ✈️",
    ],
  },
  {
    name: "rooster",
    lines: [
      "꼬끼오~ 한국 남아공 이겨라! 🐓",
      "16강 길목, 오늘이 중요해",
      "남아공 막고 골 넣자!",
      "대한민국 파이팅 🇰🇷",
      "프랑스도 한국 편이다 🙌",
      "전반부터 몰아쳐라 🐓",
      "남아공 김빠지게 골 넣자",
      "한국 미드필드 최고지",
      "오늘 분위기 우리 거야",
      "꼬끼오! 승리의 함성 📣",
    ],
  },
  {
    name: "parrot",
    lines: [
      "삼바 응원! 한국 남아공 격파 🥁",
      "골 넣고 16강 가자 💃",
      "남아공 수비 흔들어! 🔥",
      "대한민국 가즈아 🇰🇷",
      "오늘 승점 3점 챙기자 ⚽",
      "리듬 타고 골 가자 🎶",
      "남아공? 삼바로 제압! 💃",
      "한 골 한 골 쌓아가자 ⚽",
      "응원석도 파도타기 🌊",
      "오늘 MVP는 대한민국 🏆",
    ],
  },
  {
    name: "horse",
    lines: [
      "달려라 대한민국, 남아공 잡자! 🏇",
      "16강 가는 길, 오늘이 분수령",
      "남아공 골문 열어라 ⚽",
      "끝까지 응원! 한국 화이팅 📣",
      "호날두도 한국 응원한다 🐴",
      "측면 돌파로 무너뜨려!",
      "스피드로 남아공 제쳐라 🏇",
      "한 점 차도 이기면 돼",
      "16강 티켓 가져오자 🎫",
      "포르투갈도 함께 외친다 🇵🇹",
    ],
  },
];

const STEP_MS = 150;
const REST = 1;
const BUBBLE_MS = 2600;
const TAP_THRESHOLD = 6;

export default function WaveStrip() {
  const [active, setActive] = useState(-1);
  const [bubble, setBubble] = useState<{ i: number; text: string } | null>(null);
  const [off, setOff] = useState({ x: 0, y: 0 });
  const [dragging, setDragging] = useState(false);
  const lastLine = useRef<string>("");
  const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
  const drag = useRef({ px: 0, py: 0, ox: 0, oy: 0, moved: false, idx: -1 });

  // 파도타기 루프
  useEffect(() => {
    let tick = 0;
    const id = setInterval(() => {
      tick = (tick + 1) % (WAVE.length + REST);
      setActive(tick < WAVE.length ? tick : -1);
    }, STEP_MS);
    return () => clearInterval(id);
  }, []);
  useEffect(() => () => clearTimeout(timer.current), []);

  const speak = useCallback((i: number) => {
    const lines = WAVE[i].lines;
    let line = lines[Math.floor(Math.random() * lines.length)];
    if (lines.length > 1)
      while (line === lastLine.current)
        line = lines[Math.floor(Math.random() * lines.length)];
    lastLine.current = line;
    setBubble({ i, text: line });
    clearTimeout(timer.current);
    timer.current = setTimeout(() => setBubble(null), BUBBLE_MS);
  }, []);

  // 그룹 전체 드래그 + 개별 탭 구분
  const onPointerDown = useCallback(
    (e: React.PointerEvent) => {
      const el = (e.target as HTMLElement).closest("[data-idx]");
      const idx = el ? Number((el as HTMLElement).dataset.idx) : -1;
      drag.current = { px: e.clientX, py: e.clientY, ox: off.x, oy: off.y, moved: false, idx };
      setDragging(true);
      (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
    },
    [off],
  );
  const onPointerMove = useCallback(
    (e: React.PointerEvent) => {
      if (!dragging) return;
      const dx = e.clientX - drag.current.px;
      const dy = e.clientY - drag.current.py;
      if (Math.abs(dx) > TAP_THRESHOLD || Math.abs(dy) > TAP_THRESHOLD)
        drag.current.moved = true;
      setOff({ x: drag.current.ox + dx, y: drag.current.oy + dy });
    },
    [dragging],
  );
  const onPointerUp = useCallback(() => {
    setDragging(false);
    if (!drag.current.moved && drag.current.idx >= 0) speak(drag.current.idx);
  }, [speak]);

  return (
    <div
      onPointerDown={onPointerDown}
      onPointerMove={onPointerMove}
      onPointerUp={onPointerUp}
      onPointerCancel={() => setDragging(false)}
      className="flex items-end justify-end gap-0"
      style={{
        transform: `translate(${off.x}px, ${off.y}px) scale(${dragging ? 1.04 : 1})`,
        transition: dragging ? "none" : "transform 0.15s ease",
        cursor: dragging ? "grabbing" : "grab",
        touchAction: "none",
        position: "relative",
        zIndex: dragging || bubble ? 50 : 1,
      }}
    >
      {WAVE.map((a, i) => {
        const up = active === i;
        return (
          <div
            key={a.name}
            className="relative"
            style={{ zIndex: bubble?.i === i ? 50 : up ? 20 : 1, marginLeft: i ? -8 : 0 }}
          >
            {bubble?.i === i && (
              <div className="pointer-events-none absolute bottom-full left-1/2 mb-1 -translate-x-1/2 whitespace-nowrap">
                <div className="rounded-2xl bg-white px-3 py-1.5 text-[12px] font-bold text-[#1a1d22] shadow-[0_4px_14px_rgba(0,0,0,0.35)]">
                  {bubble.text}
                </div>
                <div className="mx-auto -mt-1 h-2.5 w-2.5 rotate-45 bg-white" />
              </div>
            )}
            <img
              src={`/assets/mascots/wave/${a.name}_${up ? "up" : "down"}.webp`}
              alt=""
              data-idx={i}
              draggable={false}
              className="h-9 w-auto select-none sm:h-11"
              style={{
                transform: up ? "translateY(-6px)" : "translateY(0)",
                transition: "transform 0.12s ease",
              }}
            />
          </div>
        );
      })}
    </div>
  );
}
