import { useState, useEffect, useRef, useCallback } from "react";
import { Award, RotateCcw, ArrowLeft, Volume2, Sparkles, Brain } from "lucide-react";
import { ActionButton, Card, Pill } from "../ui-kit";
import { offlineDB } from "@/lib/offline-db";

interface Pad {
  id: number;
  label: string;
  color: string;
  activeColor: string;
  freq: number;
}

const PADS: Pad[] = [
  {
    id: 0,
    label: "Red",
    color: "bg-rose-500/20 border-rose-500/40 text-rose-500",
    activeColor: "bg-rose-500 text-white shadow-rose-500/50",
    freq: 261.63,
  },
  {
    id: 1,
    label: "Blue",
    color: "bg-blue-500/20 border-blue-500/40 text-blue-500",
    activeColor: "bg-blue-500 text-white shadow-blue-500/50",
    freq: 329.63,
  },
  {
    id: 2,
    label: "Green",
    color: "bg-emerald-500/20 border-emerald-500/40 text-emerald-500",
    activeColor: "bg-emerald-500 text-white shadow-emerald-500/50",
    freq: 392.0,
  },
  {
    id: 3,
    label: "Yellow",
    color: "bg-amber-500/20 border-amber-500/40 text-amber-500",
    activeColor: "bg-amber-500 text-white shadow-amber-500/50",
    freq: 523.25,
  },
];

export function PatternRecallGame({ onBack }: { onBack: () => void }) {
  const [sequence, setSequence] = useState<number[]>([]);
  const [playerIndex, setPlayerIndex] = useState(0);
  const [activePad, setActivePad] = useState<number | null>(null);
  const [isShowingSequence, setIsShowingSequence] = useState(false);
  const [round, setRound] = useState(1);
  const [isGameOver, setIsGameOver] = useState(false);
  const [highScore, setHighScore] = useState(0);
  const audioCtxRef = useRef<AudioContext | null>(null);

  const playTone = useCallback((freq: number) => {
    try {
      if (!audioCtxRef.current) {
        const AudioContextClass =
          window.AudioContext ||
          (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext;
        audioCtxRef.current = new AudioContextClass();
      }
      const ctx = audioCtxRef.current;
      if (ctx.state === "suspended") {
        ctx.resume();
      }
      const osc = ctx.createOscillator();
      const gain = ctx.createGain();
      osc.type = "sine";
      osc.frequency.setValueAtTime(freq, ctx.currentTime);
      gain.gain.setValueAtTime(0.15, ctx.currentTime);
      gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.35);
      osc.connect(gain);
      gain.connect(ctx.destination);
      osc.start();
      osc.stop(ctx.currentTime + 0.35);
    } catch {
      // audio error fallback
    }
  }, []);

  const triggerPadLight = useCallback(
    (padId: number, durationMs = 400) => {
      setActivePad(padId);
      playTone(PADS[padId].freq);
      setTimeout(() => {
        setActivePad(null);
      }, durationMs);
    },
    [playTone],
  );

  const playSequence = useCallback(
    async (seq: number[]) => {
      setIsShowingSequence(true);
      for (let i = 0; i < seq.length; i++) {
        await new Promise((r) => setTimeout(r, 450));
        triggerPadLight(seq[i], 350);
        await new Promise((r) => setTimeout(r, 200));
      }
      setIsShowingSequence(false);
      setPlayerIndex(0);
    },
    [triggerPadLight],
  );

  const startNewGame = useCallback(() => {
    const first = Math.floor(Math.random() * 4);
    const newSeq = [first];
    setSequence(newSeq);
    setRound(1);
    setIsGameOver(false);
    setPlayerIndex(0);
    setTimeout(() => {
      playSequence(newSeq);
    }, 600);
  }, [playSequence]);

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

  const handlePadClick = async (padId: number) => {
    if (isShowingSequence || isGameOver) return;

    triggerPadLight(padId, 250);

    if (padId === sequence[playerIndex]) {
      const nextIndex = playerIndex + 1;
      if (nextIndex === sequence.length) {
        // Round completed successfully!
        const nextRound = round + 1;
        setRound(nextRound);
        setHighScore((h) => Math.max(h, round));
        const nextSeq = [...sequence, Math.floor(Math.random() * 4)];
        setSequence(nextSeq);

        setTimeout(() => {
          playSequence(nextSeq);
        }, 800);
      } else {
        setPlayerIndex(nextIndex);
      }
    } else {
      // Game Over
      setIsGameOver(true);
      const score = (round - 1) * 150;
      await offlineDB.saveGameScore({
        game_type: "pattern_recall",
        game_name: "Pattern & Audio Sequence Recall",
        score,
        moves: round,
        time_seconds: round * 4,
        difficulty: "Medium",
        stars: round > 6 ? 3 : round > 3 ? 2 : 1,
      });
    }
  };

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <button
          onClick={onBack}
          className="press flex items-center gap-1.5 text-xs font-semibold text-muted-foreground hover:text-foreground"
        >
          <ArrowLeft className="h-4 w-4" /> Sabhi Games
        </button>
        <div className="flex items-center gap-2">
          <Pill tone="primary">Round {round}</Pill>
          <Pill tone="accent">Sequence: {sequence.length}</Pill>
        </div>
      </div>

      <Card className="p-5 bg-card border border-border shadow-md text-center">
        {isGameOver ? (
          <div className="py-8 space-y-4 animate-in zoom-in-95 duration-300">
            <div className="mx-auto grid h-16 w-16 place-items-center rounded-3xl gradient-primary text-primary-foreground shadow-lg">
              <Award className="h-8 w-8" />
            </div>
            <div>
              <h4 className="font-display text-2xl font-bold">Round {round - 1} Tak Pahuche!</h4>
              <p className="text-sm text-muted-foreground mt-1">
                Aapne {round - 1} steps ka pattern safaltapurvak yaad rakha.
              </p>
              <p className="text-xs font-semibold text-emerald-600 dark:text-emerald-400 mt-1">
                ✓ Saved to Offline SQLite
              </p>
            </div>
            <div className="flex justify-center gap-3 pt-2">
              <ActionButton icon={RotateCcw} onClick={startNewGame}>
                Try Again
              </ActionButton>
              <ActionButton variant="outline" onClick={onBack}>
                Exit
              </ActionButton>
            </div>
          </div>
        ) : (
          <div className="space-y-6">
            <div>
              <h3 className="font-display text-lg font-bold">Pattern & Sound Memory</h3>
              <p className="text-xs text-muted-foreground mt-0.5">
                {isShowingSequence
                  ? "👀 Dhyan se pattern aur awaz dekhein/sunein..."
                  : `👉 Aapki baari: Pad dabayein (${playerIndex}/${sequence.length})`}
              </p>
            </div>

            {/* 4 Simon Color Pads */}
            <div className="grid grid-cols-2 gap-3 max-w-[280px] mx-auto aspect-square">
              {PADS.map((pad) => {
                const isActive = activePad === pad.id;
                return (
                  <button
                    key={pad.id}
                    onClick={() => handlePadClick(pad.id)}
                    disabled={isShowingSequence}
                    className={`press aspect-square rounded-3xl border-2 transition-all duration-150 flex items-center justify-center font-display font-bold text-lg select-none ${
                      isActive
                        ? `${pad.activeColor} scale-95 shadow-xl`
                        : `${pad.color} hover:scale-102`
                    }`}
                  >
                    {pad.label}
                  </button>
                );
              })}
            </div>

            <div className="flex items-center justify-center gap-2 text-xs text-muted-foreground">
              <Volume2 className="h-4 w-4 text-primary" />
              <span>Audio feedback tones active</span>
            </div>
          </div>
        )}
      </Card>
    </div>
  );
}
