'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
  DndContext,
  DragEndEvent,
  DragOverlay,
  DragStartEvent,
  PointerSensor,
  TouchSensor,
  useDraggable,
  useDroppable,
  useSensor,
  useSensors,
} from '@dnd-kit/core';
import { motion } from 'framer-motion';
import { ArrowLeft, RotateCcw, Check } from 'lucide-react';
import type { MatchPair } from '@/lib/content';
import Mascot from '../Mascot';
import Confetti from '../Confetti';
import { playCorrect, playWrong, playFinish } from '@/lib/sound';

function shuffle<T>(arr: T[]): T[] {
  const a = [...arr];
  for (let i = a.length - 1; i > 0; i -= 1) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

function LetterChip({ pair, done }: { pair: MatchPair; done: boolean }) {
  const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
    id: pair.id,
    disabled: done,
  });
  return (
    <button
      ref={setNodeRef}
      {...listeners}
      {...attributes}
      className={`flex h-16 w-16 items-center justify-center rounded-2xl border-2 font-heading text-3xl font-extrabold shadow-card transition
        ${
          done
            ? 'cursor-default border-leaf-500 bg-leaf-50 text-leaf-500'
            : 'cursor-grab border-mango-200 bg-white text-mango-600 active:cursor-grabbing'
        }
        ${isDragging ? 'opacity-30' : ''}`}
      style={{ touchAction: 'none' }}
    >
      {pair.letter}
    </button>
  );
}

function WordSlot({ pair, matched }: { pair: MatchPair; matched: boolean }) {
  const { setNodeRef, isOver } = useDroppable({ id: pair.id, disabled: matched });
  return (
    <div
      ref={setNodeRef}
      className={`flex items-center gap-3 rounded-3xl border-2 p-3 transition
        ${
          matched
            ? 'border-leaf-500 bg-leaf-50'
            : isOver
              ? 'border-mango-500 bg-mango-50'
              : 'border-dashed border-cream-200 bg-white'
        }`}
    >
      <div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-cream-100 text-3xl" aria-hidden>
        {pair.emoji}
      </div>
      <div className="flex-1">
        <p className="font-heading text-xl font-bold text-ink">{pair.word}</p>
        <p className="text-xs text-ink-faint">
          {matched ? 'মিলে গেছে!' : 'সঠিক বর্ণটা এখানে টেনে আনো'}
        </p>
      </div>
      <div
        className={`flex h-10 w-10 items-center justify-center rounded-xl border-2 font-heading text-2xl font-bold
          ${matched ? 'border-leaf-500 bg-white text-leaf-500' : 'border-cream-200 text-ink-faint'}`}
      >
        {matched ? <Check className="h-5 w-5" /> : '?'}
      </div>
    </div>
  );
}

export default function MatchGame({ pairs }: { pairs: MatchPair[] }) {
  const router = useRouter();
  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),
    useSensor(TouchSensor, { activationConstraint: { delay: 120, tolerance: 6 } }),
  );

  const [matched, setMatched] = useState<Set<string>>(new Set());
  const [activeId, setActiveId] = useState<string | null>(null);
  const [wrongPulse, setWrongPulse] = useState(0);
  const [confetti, setConfetti] = useState(0);

  // Shuffle only after mount so SSR and first client render match (no hydration
  // mismatch). Starts in the given order, then randomises on the client.
  const [shuffledLetters, setShuffledLetters] = useState(pairs);
  useEffect(() => {
    setShuffledLetters(shuffle(pairs));
  }, [pairs]);

  const allDone = matched.size === pairs.length;

  function onDragStart(e: DragStartEvent) {
    setActiveId(String(e.active.id));
  }

  function onDragEnd(e: DragEndEvent) {
    setActiveId(null);
    const letterId = String(e.active.id);
    const overId = e.over ? String(e.over.id) : null;
    if (!overId) return;

    if (letterId === overId) {
      playCorrect();
      const nextMatched = new Set(matched).add(letterId);
      setMatched(nextMatched);
      setConfetti((c) => c + 1);
      if (nextMatched.size === pairs.length) {
        setTimeout(() => {
          playFinish();
          setConfetti((c) => c + 1);
        }, 250);
      }
    } else {
      playWrong();
      setWrongPulse((p) => p + 1);
    }
  }

  function reset() {
    setMatched(new Set());
    setConfetti(0);
  }

  const activePair = pairs.find((p) => p.id === activeId);

  return (
    <div className="mx-auto flex min-h-dvh max-w-2xl flex-col px-4 py-4 sm:px-6">
      {confetti > 0 && <Confetti key={`mg-${confetti}`} pieces={allDone ? 44 : 20} />}

      <div className="flex items-center gap-3">
        <button
          onClick={() => router.push('/app')}
          aria-label="ফিরে যাও"
          className="rounded-full p-2 text-ink-soft transition hover:bg-cream-200"
        >
          <ArrowLeft className="h-5 w-5" />
        </button>
        <h1 className="font-heading text-xl font-extrabold text-ink">বর্ণ মিলাও</h1>
        <button
          onClick={reset}
          className="ml-auto flex items-center gap-1 rounded-full bg-cream-200 px-3 py-1.5 text-sm font-semibold text-ink-soft"
        >
          <RotateCcw className="h-4 w-4" /> নতুন করে
        </button>
      </div>

      <div className="mt-3 flex items-center gap-3 rounded-3xl bg-leaf-50 p-4">
        <Mascot mood={allDone ? 'happy' : 'idle'} size={52} />
        <p className="text-sm font-medium text-ink-soft">
          {allDone
            ? 'সব মিলে গেছে! তুমি তো দারুণ! 🎉'
            : 'প্রতিটা বর্ণ টেনে এনে সঠিক ছবির সাথে মিলাও।'}
        </p>
      </div>

      <DndContext
        sensors={sensors}
        onDragStart={onDragStart}
        onDragEnd={onDragEnd}
      >
        {/* letters to drag */}
        <motion.div
          key={wrongPulse}
          animate={wrongPulse ? { x: [0, -6, 6, -6, 0] } : {}}
          transition={{ duration: 0.35 }}
          className="mt-5 flex flex-wrap justify-center gap-3 rounded-3xl bg-white/60 p-4"
        >
          {shuffledLetters.map((p) => (
            <LetterChip key={p.id} pair={p} done={matched.has(p.id)} />
          ))}
        </motion.div>

        {/* word targets */}
        <div className="mt-5 grid gap-3 sm:grid-cols-2">
          {pairs.map((p) => (
            <WordSlot key={p.id} pair={p} matched={matched.has(p.id)} />
          ))}
        </div>

        <DragOverlay>
          {activePair ? (
            <div className="flex h-16 w-16 items-center justify-center rounded-2xl border-2 border-mango-500 bg-white font-heading text-3xl font-extrabold text-mango-600 shadow-pop">
              {activePair.letter}
            </div>
          ) : null}
        </DragOverlay>
      </DndContext>

      {allDone && (
        <motion.button
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          onClick={() => router.push('/app')}
          className="mt-6 rounded-2xl bg-leaf-500 px-5 py-3.5 font-bold text-white shadow-pop transition active:scale-[0.98]"
        >
          হোমে ফিরে যাও
        </motion.button>
      )}
    </div>
  );
}
