/**
 * Memory Game - Match LOTR character pairs
 */

import React, { useState } from 'react';
import { motion } from 'framer-motion';

interface MemoryGameProps {
  onSuccess: () => void;
  onFail: () => void;
}

export const MEMORY_SYMBOLS = ['🧙', '🧝', '🗡️', '👑', '💍', '🐴'];
export const MEMORY_MAX_ATTEMPTS = 18;

interface MemoryCard {
  id: number;
  symbol: string;
  revealed: boolean;
  matched: boolean;
}

const createCards = (): MemoryCard[] => {
  const cardPairs = [...MEMORY_SYMBOLS, ...MEMORY_SYMBOLS].sort(() => Math.random() - 0.5);

  return cardPairs.map((symbol, index) => ({
    id: index,
    symbol,
    revealed: false,
    matched: false,
  }));
};

export const MemoryGame: React.FC<MemoryGameProps> = ({ onSuccess, onFail }) => {
  const [cards, setCards] = useState<MemoryCard[]>(() => createCards());
  const [selectedCards, setSelectedCards] = useState<number[]>([]);
  const [matchedPairs, setMatchedPairs] = useState(0);
  const [attempts, setAttempts] = useState(0);
  const [isResolving, setIsResolving] = useState(false);
  const [showFail, setShowFail] = useState(false);

  const handleCardClick = (index: number) => {
    if (
      isResolving ||
      showFail ||
      selectedCards.length >= 2 ||
      cards[index].matched ||
      cards[index].revealed ||
      selectedCards.includes(index)
    ) {
      return;
    }

    const nextSelectedCards = [...selectedCards, index];
    setCards((prev) => prev.map((card, idx) => (idx === index ? { ...card, revealed: true } : card)));
    setSelectedCards(nextSelectedCards);

    if (nextSelectedCards.length !== 2) {
      return;
    }

    const [firstIndex, secondIndex] = nextSelectedCards;
    const isMatch = cards[firstIndex].symbol === cards[secondIndex].symbol;
    const nextAttempts = attempts + 1;

    setIsResolving(true);
    setAttempts(nextAttempts);

    if (isMatch) {
      window.setTimeout(() => {
        setCards((prev) =>
          prev.map((card, idx) =>
            idx === firstIndex || idx === secondIndex ? { ...card, matched: true } : card
          )
        );

        const nextMatchedPairs = matchedPairs + 1;
        setMatchedPairs(nextMatchedPairs);
        setSelectedCards([]);
        setIsResolving(false);

        if (nextMatchedPairs === MEMORY_SYMBOLS.length) {
          window.setTimeout(() => {
            onSuccess();
          }, 300);
        }
      }, 450);

      return;
    }

    if (nextAttempts >= MEMORY_MAX_ATTEMPTS) {
      setShowFail(true);
      window.setTimeout(() => {
        onFail();
      }, 900);
      return;
    }

    window.setTimeout(() => {
      setCards((prev) =>
        prev.map((card, idx) =>
          idx === firstIndex || idx === secondIndex ? { ...card, revealed: false } : card
        )
      );
      setSelectedCards([]);
      setIsResolving(false);
    }, 800);
  };

  return (
    <div className="space-y-4">
      <motion.div
        initial={{ opacity: 0, y: -10 }}
        animate={{ opacity: 1, y: 0 }}
        className="text-center"
      >
        <h3 className="text-xl font-epic text-gold-dark mb-2">🎭 Memory Game</h3>
        <div className="flex items-center justify-center gap-4 text-sm text-text-secondary flex-wrap">
          <p>Pairs: {matchedPairs}/{MEMORY_SYMBOLS.length}</p>
          <p>Attempts: {attempts}/{MEMORY_MAX_ATTEMPTS}</p>
        </div>
      </motion.div>

      {showFail && (
        <motion.div
          initial={{ opacity: 0, scale: 0.9 }}
          animate={{ opacity: 1, scale: 1 }}
          className="text-center text-red-400 font-semibold"
        >
          ✗ Attempt limit reached. Resetting challenge...
        </motion.div>
      )}

      <div className="grid grid-cols-4 gap-2 sm:gap-3">
        {cards.map((card, index) => (
          <motion.button
            key={card.id}
            type="button"
            aria-label={`Memory card ${index + 1}`}
            onClick={() => handleCardClick(index)}
            disabled={card.matched || card.revealed || selectedCards.length >= 2 || isResolving || showFail}
            whileHover={{ scale: card.matched || card.revealed || isResolving || showFail ? 1 : 1.04 }}
            whileTap={{ scale: card.matched || card.revealed || isResolving || showFail ? 1 : 0.97 }}
            className={`aspect-square rounded-lg text-2xl flex items-center justify-center transition-all duration-300 ${
              card.matched
                ? 'bg-green-600 cursor-default'
                : card.revealed
                ? 'bg-gold cursor-default text-forest-dark'
                : 'bg-forest hover:bg-forest-light cursor-pointer text-transparent'
            }`}
          >
            <motion.div
              initial={{ rotateY: 90 }}
              animate={{ rotateY: card.revealed || card.matched ? 0 : 90 }}
              transition={{ duration: 0.25 }}
            >
              {(card.revealed || card.matched) && card.symbol}
            </motion.div>
          </motion.button>
        ))}
      </div>

      {matchedPairs === MEMORY_SYMBOLS.length && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          className="text-center text-green-400 font-semibold"
        >
          ✓ All pairs matched!
        </motion.div>
      )}
    </div>
  );
};

MemoryGame.displayName = 'MemoryGame';
