"use client";

import { useState, useEffect, useCallback } from "react";
import { motion } from "framer-motion";
import {
  Moon,
  Sun,
  Star,
  Rocket,
  Sparkles,
  Orbit,
  Satellite,
  Eclipse,
  Brain,
} from "lucide-react";
import { MiniGameResultsScreen } from "@/components/game/MiniGameResultsScreen";
import { MiniGameHeader } from "@/components/game/MiniGameHeader";
import { soundManager } from "@/lib/sound/manager";
import { fireCelebration } from "@/lib/confetti";

const CARD_ICONS = [Moon, Sun, Star, Rocket, Sparkles, Orbit, Satellite, Eclipse];

function nowMs(): number {
  return Date.now();
}

type CardItem = {
  id: number;
  iconId: number;
  Icon: React.ComponentType<{ size?: number; className?: string }>;
  isFlipped: boolean;
  isMatched: boolean;
};

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

function createCards(): CardItem[] {
  const pairs: CardItem[] = [];
  CARD_ICONS.forEach((Icon, index) => {
    pairs.push({ id: index * 2, iconId: index, Icon, isFlipped: false, isMatched: false });
    pairs.push({ id: index * 2 + 1, iconId: index, Icon, isFlipped: false, isMatched: false });
  });
  return shuffleArray(pairs);
}

export default function MemoryGame() {

  const [cards, setCards] = useState<CardItem[]>([]);
  const [moves, setMoves] = useState(0);
  const [flippedIndices, setFlippedIndices] = useState<number[]>([]);
  const [isLocked, setIsLocked] = useState(false);
  const [isWon, setIsWon] = useState(false);
  const [timeStart, setTimeStart] = useState<number | null>(null);
  const [timeElapsed, setTimeElapsed] = useState(0);
  const [isStarted, setIsStarted] = useState(false);

  const initGame = useCallback(() => {
    setCards(createCards());
    setMoves(0);
    setFlippedIndices([]);
    setIsLocked(false);
    setIsWon(false);
    setTimeStart(null);
    setTimeElapsed(0);
    setIsStarted(false);
  }, []);

  // Initialize on mount
  useEffect(() => {
    const timer = setTimeout(() => {
      initGame();
    }, 0);
    return () => clearTimeout(timer);
  }, [initGame]);

  // Timer
  useEffect(() => {
    if (!timeStart || isWon) return;
    const interval = setInterval(() => {
      setTimeElapsed(Math.floor((Date.now() - timeStart) / 1000));
    }, 1000);
    return () => clearInterval(interval);
  }, [timeStart, isWon]);

  const handleCardClick = (index: number) => {
    if (isLocked || isWon) return;
    const card = cards[index];
    if (card.isFlipped || card.isMatched) return;

    // Start timer on first card flip
    if (!timeStart) {
      setTimeStart(nowMs());
      setIsStarted(true);
    }

    soundManager.play("click");

    const newCards = [...cards];
    newCards[index] = { ...newCards[index], isFlipped: true };
    setCards(newCards);

    const newFlipped = [...flippedIndices, index];
    setFlippedIndices(newFlipped);

    if (newFlipped.length === 2) {
      setMoves((prev) => prev + 1);
      const [first, second] = newFlipped;

      if (newCards[first].iconId === newCards[second].iconId) {
        // Match found
        soundManager.play("correct");
        const matched = newCards.map((c) =>
          c.iconId === newCards[first].iconId ? { ...c, isMatched: true } : c,
        );
        setCards(matched);
        setFlippedIndices([]);

        // Check win condition
        if (matched.every((c) => c.isMatched)) {
          setIsWon(true);
          fireCelebration();
          soundManager.play("victory");
        }
      } else {
        // No match -- flip back after a short delay
        soundManager.play("wrong");
        setIsLocked(true);
        setTimeout(() => {
          const flippedBack = newCards.map((c, i) =>
            i === first || i === second ? { ...c, isFlipped: false } : c,
          );
          setCards(flippedBack);
          setFlippedIndices([]);
          setIsLocked(false);
        }, 800);
      }
    }
  };

  const matchedCount = cards.filter((c) => c.isMatched).length / 2;

  const formatTime = (seconds: number) => {
    const m = Math.floor(seconds / 60);
    const s = seconds % 60;
    return `${m}:${s.toString().padStart(2, "0")}`;
  };

  if (isWon) {
    return (
      <MiniGameResultsScreen
        gameId="memory"
        score={moves}
        stats={[
          { label: "Moves", value: `${moves}` },
          { label: "Time", value: formatTime(timeElapsed) },
          { label: "Pairs Found", value: `${CARD_ICONS.length}` },
        ]}
        onPlayAgain={initGame}
      />
    );
  }

  return (
    <div className="flex-1 flex flex-col w-full max-w-2xl mx-auto items-center gap-4 px-4">
      <MiniGameHeader
        title="Memory Match"
        icon={Brain}
        accentColor="cyan"
        stats={[
          { label: "Moves", value: `${moves}` },
          { label: "Pairs", value: `${matchedCount} / ${CARD_ICONS.length}` },
          { label: "Time", value: formatTime(timeElapsed) },
        ]}
      />

      {!isStarted && cards.length > 0 && (
        <p className="text-slate-400 text-sm text-center">
          Tap any card to begin. Match all pairs in as few moves as possible.
        </p>
      )}

      <div className="grid grid-cols-4 gap-3 w-full max-w-md mt-4">
        {cards.map((card, index) => {
          const isRevealed = card.isFlipped || card.isMatched;
          return (
            <div
              key={card.id}
              onClick={() => handleCardClick(index)}
              className="relative cursor-pointer aspect-square"
              style={{ perspective: "1000px" }}
            >
              <motion.div
                className="absolute inset-0"
                style={{ transformStyle: "preserve-3d" }}
                animate={{ rotateY: isRevealed ? 180 : 0 }}
                transition={{ duration: 0.4, ease: "easeInOut" }}
              >
                {/* Card Back */}
                <div
                  className="absolute inset-0 rounded-xl bg-gradient-to-br from-indigo-600/80 to-purple-700/80 border border-white/20 flex items-center justify-center shadow-lg hover:border-cyan-400/50 transition-colors"
                  style={{ backfaceVisibility: "hidden" }}
                >
                  <Star size={24} className="text-white/30" />
                </div>

                {/* Card Front */}
                <div
                  className={`absolute inset-0 rounded-xl flex items-center justify-center border shadow-lg transition-colors ${
                    card.isMatched
                      ? "bg-gradient-to-br from-green-600/80 to-emerald-700/80 border-green-400/50"
                      : "bg-gradient-to-br from-cyan-600/80 to-blue-700/80 border-cyan-400/50"
                  }`}
                  style={{
                    backfaceVisibility: "hidden",
                    transform: "rotateY(180deg)",
                  }}
                >
                  <card.Icon
                    size={32}
                    className={card.isMatched ? "text-green-200" : "text-white"}
                  />
                </div>
              </motion.div>
            </div>
          );
        })}
      </div>
    </div>
  );
}
