'use client';

import { useMemo, useRef, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { motion, AnimatePresence } from 'framer-motion';
import { Heart, Star, Check, X, ArrowLeft, RotateCcw, ArrowRight, Puzzle, Coins } from 'lucide-react';
import type { Question } from '@/lib/types';
import Mascot from '../Mascot';
import Confetti from '../Confetti';
import SpeakButton from '../SpeakButton';
import { playCorrect, playWrong, playFinish } from '@/lib/sound';
import { bn } from '@/lib/bn';

type Accent = 'mango' | 'leaf' | 'sun';

const ACCENT: Record<Accent, { solid: string; soft: string; text: string; hover: string }> = {
  mango: { solid: 'bg-mango-500', soft: 'bg-mango-50', text: 'text-mango-700', hover: 'hover:border-mango-500' },
  leaf: { solid: 'bg-leaf-500', soft: 'bg-leaf-50', text: 'text-leaf-700', hover: 'hover:border-leaf-500' },
  sun: { solid: 'bg-sun-500', soft: 'bg-sun-50', text: 'text-sun-600', hover: 'hover:border-sun-500' },
};

const CHEER = ['দারুণ! 🎉', 'একদম ঠিক! ⭐', 'সাবাশ! 👏', 'তুমি পারো! 💪', 'দুর্দান্ত! 🌟'];
const NUDGE = ['আরেকবার চেষ্টা করো!', 'প্রায় পেরেছ, আবার দেখো!', 'ভয় নেই, আবার ভাবো!', 'তুমি পারবে, চেষ্টা করো!'];

const START_LIVES = 3;

export default function QuizRunner({
  subjectId,
  subjectName,
  accent,
  lessonId,
  levelId,
  questions,
  rewardCoins = 0,
  hasMatchGame,
  autoRead = false,
  backHref = '/app',
}: {
  subjectId: string;
  subjectName: string;
  accent: Accent;
  lessonId: string;
  levelId?: string;
  questions: Question[];
  rewardCoins?: number;
  hasMatchGame: boolean;
  autoRead?: boolean;
  backHref?: string;
}) {
  const router = useRouter();
  const a = ACCENT[accent];
  const startedAt = useRef(Date.now());
  const [coinsEarned, setCoinsEarned] = useState(0);

  const [index, setIndex] = useState(0);
  const [selected, setSelected] = useState<number | null>(null);
  const [locked, setLocked] = useState(false); // correct answer chosen -> can advance
  const [wrongThisQ, setWrongThisQ] = useState(false);
  const [lives, setLives] = useState(START_LIVES);
  const [stars, setStars] = useState(0);
  const [firstTryCorrect, setFirstTryCorrect] = useState(0);
  const [message, setMessage] = useState('');
  const [confetti, setConfetti] = useState(0); // increment to retrigger
  const [finished, setFinished] = useState(false);
  const [saved, setSaved] = useState(false);

  const total = questions.length;
  const q = questions[index];
  const progressPct = Math.round(((index + (locked ? 1 : 0)) / total) * 100);

  function pick(i: number) {
    if (locked) return;
    setSelected(i);
    if (i === q.correctIndex) {
      playCorrect();
      setLocked(true);
      setConfetti((c) => c + 1);
      setMessage(CHEER[Math.floor(Math.random() * CHEER.length)]);
      if (!wrongThisQ) {
        setStars((s) => s + 1);
        setFirstTryCorrect((n) => n + 1);
      }
    } else {
      playWrong();
      setWrongThisQ(true);
      setLives((l) => Math.max(0, l - 1));
      setMessage(NUDGE[Math.floor(Math.random() * NUDGE.length)]);
      // brief shake, then let them try again
      setTimeout(() => setSelected(null), 500);
    }
  }

  function next() {
    if (index + 1 >= total) {
      finish();
      return;
    }
    setIndex((n) => n + 1);
    setSelected(null);
    setLocked(false);
    setWrongThisQ(false);
    setMessage('');
  }

  async function finish() {
    playFinish();
    setFinished(true);
    const durationSeconds = Math.round((Date.now() - startedAt.current) / 1000);
    try {
      const res = await fetch('/api/progress', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          subjectId,
          lessonId,
          levelId,
          stars,
          durationSeconds,
          correctCount: firstTryCorrect,
          totalCount: total,
          rewardCoins,
        }),
      });
      const data = await res.json().catch(() => ({}));
      if (typeof data.coinsEarned === 'number') setCoinsEarned(data.coinsEarned);
      setSaved(true);
    } catch {
      setSaved(true); // don't block the UI on a network hiccup
    }
  }

  function restart() {
    setIndex(0);
    setSelected(null);
    setLocked(false);
    setWrongThisQ(false);
    setLives(START_LIVES);
    setStars(0);
    setFirstTryCorrect(0);
    setMessage('');
    setFinished(false);
    setSaved(false);
    startedAt.current = Date.now();
  }

  const correctPct = total > 0 ? Math.round((firstTryCorrect / total) * 100) : 0;

  /* --------------------------- summary screen --------------------------- */
  if (finished) {
    return (
      <div className="mx-auto flex min-h-dvh max-w-md flex-col items-center justify-center px-5 py-10 text-center">
        {confetti > 0 && <Confetti key={`fin-${confetti}`} pieces={40} />}
        <Mascot mood="happy" size={130} />
        <h1 className="mt-4 font-heading text-3xl font-extrabold text-ink">লেসন শেষ! 🎉</h1>
        <p className="mt-1 text-ink-soft">{subjectName}, দারুণ খেলেছ!</p>

        <div className="mt-6 grid w-full grid-cols-2 gap-3">
          <div className="rounded-3xl bg-sun-50 p-5">
            <Star className="mx-auto h-8 w-8 fill-sun-500 text-sun-500" />
            <p className="mt-2 font-heading text-3xl font-extrabold text-ink">{bn(stars)}</p>
            <p className="text-xs text-ink-soft">স্টার পেয়েছ</p>
          </div>
          <div className="rounded-3xl bg-leaf-50 p-5">
            <Check className="mx-auto h-8 w-8 text-leaf-600" />
            <p className="mt-2 font-heading text-3xl font-extrabold text-ink">{bn(correctPct)}%</p>
            <p className="text-xs text-ink-soft">সঠিক উত্তর</p>
          </div>
        </div>

        {coinsEarned > 0 && (
          <div className="mt-3 flex items-center justify-center gap-2 rounded-2xl bg-mango-50 px-4 py-3 font-bold text-mango-700">
            <Coins className="h-5 w-5" />+{bn(coinsEarned)} কয়েন পেলে!
          </div>
        )}

        <div className="mt-7 flex w-full flex-col gap-3">
          <button
            onClick={restart}
            className={`flex items-center justify-center gap-2 rounded-2xl ${a.solid} px-5 py-3.5 font-bold text-white shadow-pop transition active:scale-[0.98]`}
          >
            <RotateCcw className="h-5 w-5" /> আবার খেলো
          </button>
          {hasMatchGame && (
            <Link
              href="/app/game"
              className="flex items-center justify-center gap-2 rounded-2xl bg-white px-5 py-3.5 font-bold text-ink shadow-card transition active:scale-[0.98]"
            >
              <Puzzle className="h-5 w-5 text-leaf-600" /> ম্যাচিং গেম খেলো
            </Link>
          )}
          <button
            onClick={() => router.push(backHref)}
            className="flex items-center justify-center gap-2 rounded-2xl bg-cream-200 px-5 py-3.5 font-bold text-ink-soft transition active:scale-[0.98]"
          >
            আরও লেভেল <ArrowRight className="h-5 w-5" />
          </button>
        </div>
        {!saved && <p className="mt-3 text-xs text-ink-faint">প্রগ্রেস সেভ হচ্ছে…</p>}
      </div>
    );
  }

  /* ----------------------------- quiz screen ----------------------------- */
  return (
    <div className="mx-auto flex min-h-dvh max-w-2xl flex-col px-4 py-4 sm:px-6">
      {confetti > 0 && locked && <Confetti key={`c-${confetti}`} />}

      {/* top bar: back, progress, lives */}
      <div className="flex items-center gap-3">
        <button
          onClick={() => router.push(backHref)}
          aria-label="ফিরে যাও"
          className="rounded-full p-2 text-ink-soft transition hover:bg-cream-200"
        >
          <ArrowLeft className="h-5 w-5" />
        </button>
        <div className="h-3 flex-1 overflow-hidden rounded-full bg-cream-200">
          <motion.div
            className={`h-full rounded-full ${a.solid}`}
            animate={{ width: `${progressPct}%` }}
            transition={{ type: 'spring', stiffness: 200, damping: 30 }}
          />
        </div>
        <div className="flex items-center gap-0.5" aria-label={`জীবন ${lives}`}>
          {Array.from({ length: START_LIVES }).map((_, i) => (
            <Heart
              key={i}
              className={`h-5 w-5 ${i < lives ? 'fill-mango-500 text-mango-500' : 'text-cream-200'}`}
            />
          ))}
        </div>
      </div>

      {/* mascot + question */}
      <div className="mt-6 flex items-start gap-3">
        <Mascot mood={locked ? 'happy' : selected != null ? 'sad' : 'idle'} size={64} />
        <motion.div
          key={q.id}
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          className="flex-1 rounded-3xl bg-white p-5 shadow-card"
        >
          <div className="flex items-start justify-between gap-2">
            <p className="text-xs font-semibold text-ink-faint">
              প্রশ্ন {bn(index + 1)} / {bn(total)}
            </p>
            <SpeakButton key={q.id} text={q.question} autoPlay={autoRead} size="sm" />
          </div>
          <h2 className="mt-1 font-heading text-xl font-bold leading-snug text-ink sm:text-2xl">
            {q.question}
          </h2>
        </motion.div>
      </div>

      {/* options */}
      <div className="mt-5 grid gap-3 sm:grid-cols-2">
        {q.options.map((opt, i) => {
          const isSelected = selected === i;
          const isCorrect = locked && i === q.correctIndex;
          const isWrongPick = isSelected && i !== q.correctIndex;
          return (
            <motion.button
              key={i}
              disabled={locked}
              onClick={() => pick(i)}
              animate={isWrongPick ? { x: [0, -8, 8, -8, 8, 0] } : {}}
              transition={{ duration: 0.4 }}
              whileTap={{ scale: locked ? 1 : 0.97 }}
              className={`flex min-h-[56px] items-center justify-between gap-2 rounded-2xl border-2 px-4 py-3.5 text-left text-lg font-semibold transition
                ${
                  isCorrect
                    ? 'border-leaf-500 bg-leaf-50 text-leaf-700'
                    : isWrongPick
                      ? 'border-mango-500 bg-mango-50 text-mango-700'
                      : `border-cream-200 bg-white text-ink ${a.hover}`
                }`}
            >
              <span>{opt}</span>
              {isCorrect && <Check className="h-6 w-6 shrink-0 text-leaf-600" />}
              {isWrongPick && <X className="h-6 w-6 shrink-0 text-mango-600" />}
            </motion.button>
          );
        })}
      </div>

      {/* feedback + advance */}
      <div className="mt-5 min-h-[96px]">
        <AnimatePresence mode="wait">
          {message && (
            <motion.div
              key={message + index + (locked ? 'ok' : 'try')}
              initial={{ opacity: 0, y: 8 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0 }}
              className={`rounded-2xl px-4 py-3 text-center font-bold ${
                locked ? 'bg-leaf-50 text-leaf-700' : 'bg-sun-50 text-sun-600'
              }`}
            >
              {message}
              {locked && q.explanation && (
                <p className="mt-1 text-sm font-medium text-ink-soft">{q.explanation}</p>
              )}
            </motion.div>
          )}
        </AnimatePresence>

        {locked && (
          <motion.button
            initial={{ opacity: 0, y: 8 }}
            animate={{ opacity: 1, y: 0 }}
            onClick={next}
            className={`mt-3 flex w-full items-center justify-center gap-2 rounded-2xl ${a.solid} px-5 py-3.5 font-bold text-white shadow-pop transition active:scale-[0.98]`}
          >
            {index + 1 >= total ? 'শেষ করো' : 'পরের প্রশ্ন'}
            <ArrowRight className="h-5 w-5" />
          </motion.button>
        )}
      </div>
    </div>
  );
}
