import React, { useState, useEffect, useCallback } from 'react';
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  Dimensions
} from 'react-native';
import { BaseGame, GameFactory } from '../base/BaseGame';
import { 
  GameConfig, 
  GameResult, 
  PlayerAction, 
  GameDifficulty, 
  GameStatus,
  GameState
} from '../../core/types';

interface Card {
  id: string;
  value: string;
  isFlipped: boolean;
  isMatched: boolean;
}

interface MemoryGameState extends GameState {
  cards: Card[];
  flippedCards: string[];
  matches: number;
  attempts: number;
}

/**
 * Memory Match Game Implementation
 */
export class MemoryMatchGame extends BaseGame {
  readonly gameId = 'memory-match';
  readonly name = 'משחק זיכרון';
  readonly description = 'מצא את הזוגות התואמים';
  readonly category = 'memory';
  readonly version = '1.0.0';
  readonly minDifficulty = GameDifficulty.EASY;
  readonly maxDifficulty = GameDifficulty.EXPERT;
  readonly estimatedDuration = 5; // minutes

  private gameState!: MemoryGameState;
  private gridSize: number = 4;
  private totalPairs: number = 8;
  private symbols = ['🐕', '🐶', '🦮', '🐕‍🦺', '🐩', '🐺', '🦊', '🐱', '🐈', '🐈‍⬛', '🦁', '🐯', '🐅', '🐆', '🐘', '🦒'];

  async initializeGameLogic(): Promise<void> {
    this.setupDifficulty();
    this.generateCards();
    
    this.gameState = {
      ...this.createInitialState(),
      cards: this.generateCards(),
      flippedCards: [],
      matches: 0,
      attempts: 0
    } as MemoryGameState;
  }

  startGameLogic(): void {
    // משחק מתחיל מיד כשמתחילים
    this.trackCustomEvent('memory_game_started', {
      gridSize: this.gridSize,
      totalPairs: this.totalPairs,
      difficulty: this.config.difficulty
    });
  }

  pauseGameLogic(): void {
    // במשחק זיכרון, pause פשוט עוצר את הטיימר
  }

  resumeGameLogic(): void {
    // המשך הטיימר
  }

  restartGameLogic(): void {
    this.generateCards();
    this.gameState = {
      ...this.createInitialState(),
      cards: this.generateCards(),
      flippedCards: [],
      matches: 0,
      attempts: 0
    } as MemoryGameState;
  }

  endGameLogic(): GameResult {
    const timeSpent = this.getElapsedTime();
    const baseScore = this.calculateMemoryScore();
    
    return {
      gameId: this.gameId,
      playerId: this.gameState.gameSpecificData.playerId || 'anonymous',
      score: baseScore,
      maxScore: 1000,
      timeSpent,
      completed: this.gameState.matches === this.totalPairs,
      difficulty: this.config.difficulty,
      customData: {
        matches: this.gameState.matches,
        attempts: this.gameState.attempts,
        accuracy: this.gameState.attempts > 0 ? (this.gameState.matches / this.gameState.attempts) * 100 : 0,
        gridSize: this.gridSize
      },
      timestamp: new Date(),
      sessionId: this.sessionId,
      moves: this.gameState.attempts
    };
  }

  processPlayerAction(action: PlayerAction): void {
    if (action.type === 'FLIP_CARD') {
      this.flipCard(action.payload.cardId);
    }
  }

  validateGameConfig(config: GameConfig): boolean {
    return config.gameId === this.gameId;
  }

  /**
   * Game-specific methods
   */
  private setupDifficulty(): void {
    switch (this.config.difficulty) {
      case GameDifficulty.EASY:
        this.gridSize = 3;
        this.totalPairs = 4;
        break;
      case GameDifficulty.MEDIUM:
        this.gridSize = 4;
        this.totalPairs = 8;
        break;
      case GameDifficulty.HARD:
        this.gridSize = 5;
        this.totalPairs = 12;
        break;
      case GameDifficulty.EXPERT:
        this.gridSize = 6;
        this.totalPairs = 18;
        break;
    }
  }

  private generateCards(): Card[] {
    const selectedSymbols = this.symbols.slice(0, this.totalPairs);
    const cardValues = [...selectedSymbols, ...selectedSymbols]; // Create pairs
    
    // Shuffle the cards
    for (let i = cardValues.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [cardValues[i], cardValues[j]] = [cardValues[j], cardValues[i]];
    }

    return cardValues.map((value, index) => ({
      id: `card-${index}`,
      value,
      isFlipped: false,
      isMatched: false
    }));
  }

  private flipCard(cardId: string): void {
    if (this.state.status !== GameStatus.PLAYING) return;

    const card = this.gameState.cards.find(c => c.id === cardId);
    if (!card || card.isFlipped || card.isMatched) return;

    // Flip the card
    card.isFlipped = true;
    this.gameState.flippedCards.push(cardId);

    // Check for match when two cards are flipped
    if (this.gameState.flippedCards.length === 2) {
      this.gameState.attempts++;
      this.checkForMatch();
    }

    // Check win condition
    if (this.gameState.matches === this.totalPairs) {
      this.state.status = GameStatus.COMPLETED;
      this.end();
    }

    this.updateTime();
  }

  private checkForMatch(): void {
    const [firstCardId, secondCardId] = this.gameState.flippedCards;
    const firstCard = this.gameState.cards.find(c => c.id === firstCardId)!;
    const secondCard = this.gameState.cards.find(c => c.id === secondCardId)!;

    if (firstCard.value === secondCard.value) {
      // Match found!
      firstCard.isMatched = true;
      secondCard.isMatched = true;
      this.gameState.matches++;
      
      this.updateScore(100); // Points for match
      
      this.trackCustomEvent('memory_match_found', {
        attempts: this.gameState.attempts,
        matches: this.gameState.matches,
        totalPairs: this.totalPairs
      });
    } else {
      // No match - flip cards back after delay
      setTimeout(() => {
        firstCard.isFlipped = false;
        secondCard.isFlipped = false;
      }, 1000);
    }

    this.gameState.flippedCards = [];
  }

  private calculateMemoryScore(): number {
    const baseScore = this.gameState.matches * 100;
    const accuracyBonus = this.gameState.attempts > 0 ? 
      Math.floor((this.gameState.matches / this.gameState.attempts) * 200) : 0;
    
    return this.calculateScore(baseScore + accuracyBonus);
  }

  /**
   * Get current game state for UI
   */
  getMemoryState(): MemoryGameState {
    return { ...this.gameState };
  }

  /**
   * React Component for the game
   */
  createGameComponent(): React.FC {
    return () => {
      const [gameState, setGameState] = useState<MemoryGameState>(this.getMemoryState());
      const [isProcessing, setIsProcessing] = useState(false);

      useEffect(() => {
        const interval = setInterval(() => {
          setGameState(this.getMemoryState());
        }, 100);

        return () => clearInterval(interval);
      }, []);

      const handleCardPress = useCallback(async (cardId: string) => {
        if (isProcessing) return;
        
        setIsProcessing(true);
        this.onPlayerAction({
          type: 'FLIP_CARD',
          payload: { cardId },
          timestamp: new Date()
        });
        
        setTimeout(() => setIsProcessing(false), 1100);
      }, [isProcessing]);

      const renderCard = (card: Card, index: number) => (
        <TouchableOpacity
          key={card.id}
          style={[
            styles.card,
            card.isFlipped || card.isMatched ? styles.cardFlipped : styles.cardHidden,
            card.isMatched && styles.cardMatched
          ]}
          onPress={() => handleCardPress(card.id)}
          disabled={card.isFlipped || card.isMatched || isProcessing}
        >
          <Text style={styles.cardText}>
            {card.isFlipped || card.isMatched ? card.value : '?'}
          </Text>
        </TouchableOpacity>
      );

      return (
        <View style={styles.container}>
          <View style={styles.header}>
            <Text style={styles.title}>משחק זיכרון</Text>
            <View style={styles.stats}>
              <Text style={styles.statText}>ניקוד: {gameState.currentScore}</Text>
              <Text style={styles.statText}>זוגות: {gameState.matches}/{this.totalPairs}</Text>
              <Text style={styles.statText}>ניסיונות: {gameState.attempts}</Text>
            </View>
          </View>
          
          <View style={[styles.gameBoard, { flexDirection: 'row', flexWrap: 'wrap' }]}>
            {gameState.cards.map((card, index) => renderCard(card, index))}
          </View>

          {gameState.status === GameStatus.COMPLETED && (
            <View style={styles.completedOverlay}>
              <Text style={styles.completedText}>כל הכבוד!</Text>
              <Text style={styles.completedScore}>ניקוד סופי: {gameState.currentScore}</Text>
            </View>
          )}
        </View>
      );
    };
  }
}

/**
 * Factory for creating Memory Match game instances
 */
export class MemoryMatchGameFactory implements GameFactory {
  createGame(): BaseGame {
    return new MemoryMatchGame();
  }

  getGameInfo() {
    return {
      id: 'memory-match',
      name: 'משחק זיכרון',
      description: 'מצא את הזוגות התואמים',
      category: 'memory',
      thumbnail: '🧠',
      version: '1.0.0'
    };
  }
}

// Export the React component for external use
export { MemoryMatchGameComponent } from './MemoryMatchGameComponent';

const { width } = Dimensions.get('window');
const cardSize = (width - 60) / 4;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
    padding: 20,
  },
  header: {
    alignItems: 'center',
    marginBottom: 20,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#333',
    marginBottom: 10,
  },
  stats: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    width: '100%',
  },
  statText: {
    fontSize: 16,
    color: '#666',
    fontWeight: '600',
  },
  gameBoard: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  card: {
    width: cardSize,
    height: cardSize,
    margin: 4,
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
    elevation: 3,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  cardHidden: {
    backgroundColor: '#4a90e2',
  },
  cardFlipped: {
    backgroundColor: '#fff',
    borderWidth: 2,
    borderColor: '#4a90e2',
  },
  cardMatched: {
    backgroundColor: '#5cb85c',
    borderColor: '#5cb85c',
  },
  cardText: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#fff',
  },
  completedOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: 'rgba(0,0,0,0.8)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  completedText: {
    fontSize: 32,
    fontWeight: 'bold',
    color: '#fff',
    marginBottom: 20,
  },
  completedScore: {
    fontSize: 24,
    color: '#5cb85c',
    fontWeight: '600',
  },
});
