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

interface ImageTile {
  id: string;
  originalIndex: number;
  currentIndex: number;
  imageUrl: string;
  isCorrect: boolean;
}

interface ImagePuzzleGameState extends GameState {
  tiles: ImageTile[];
  gridSize: number;
  moves: number;
  isComplete: boolean;
  selectedTile: string | null;
}

interface ImagePuzzleGameProps {
  gridSize?: number;
  difficulty?: 'easy' | 'medium' | 'hard';
  imageUrl?: string;
  onGameComplete?: (result: any) => void;
  onGameStart?: () => void;
  onMove?: (moveData: any) => void;
  showMenu?: boolean;
  autoStart?: boolean;
  title?: string;
  subtitle?: string;
  showStats?: boolean;
  enableHints?: boolean;
  enableReset?: boolean;
  theme?: {
    primaryColor?: string;
    secondaryColor?: string;
    backgroundColor?: string;
    textColor?: string;
  };
}

/**
 * Image Puzzle Game Implementation
 */
export class ImagePuzzleGame extends BaseGame {
  readonly gameId = 'image-puzzle';
  readonly name = 'פאזל תמונה';
  readonly description = 'סדר את חלקי התמונה למקומם הנכון';
  readonly category = 'puzzle';
  readonly version = '1.0.0';
  readonly minDifficulty = GameDifficulty.EASY;
  readonly maxDifficulty = GameDifficulty.EXPERT;
  readonly estimatedDuration = 10; // minutes

  private gameState!: ImagePuzzleGameState;
  private gridSize: number = 3;
  private imageUrl: string = 'https://picsum.photos/300/300';

  async initializeGameLogic(): Promise<void> {
    this.setupDifficulty();
    this.gameState = {
      ...this.createInitialState(),
      tiles: this.generateTiles(),
      gridSize: this.gridSize,
      moves: 0,
      isComplete: false,
      selectedTile: null
    } as ImagePuzzleGameState;
  }

  startGameLogic(): void {
    this.trackCustomEvent('image_puzzle_started', {
      gridSize: this.gridSize,
      difficulty: this.config.difficulty
    });
  }

  pauseGameLogic(): void {
    // Pause logic for image puzzle
  }

  resumeGameLogic(): void {
    // Resume logic for image puzzle
  }

  restartGameLogic(): void {
    this.gameState = {
      ...this.createInitialState(),
      tiles: this.generateTiles(),
      gridSize: this.gridSize,
      moves: 0,
      isComplete: false,
      selectedTile: null
    } as ImagePuzzleGameState;
  }

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

  processPlayerAction(action: PlayerAction): void {
    if (action.type === 'SELECT_TILE') {
      this.selectTile(action.payload.tileId);
    } else if (action.type === 'SWAP_TILES') {
      this.swapTiles(action.payload.tile1Id, action.payload.tile2Id);
    }
  }

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

  private setupDifficulty(): void {
    switch (this.config.difficulty) {
      case GameDifficulty.EASY:
        this.gridSize = 3;
        break;
      case GameDifficulty.MEDIUM:
        this.gridSize = 4;
        break;
      case GameDifficulty.HARD:
        this.gridSize = 5;
        break;
      case GameDifficulty.EXPERT:
        this.gridSize = 6;
        break;
    }
  }

  private generateTiles(): ImageTile[] {
    const totalTiles = this.gridSize * this.gridSize;
    const tiles: ImageTile[] = [];
    
    for (let i = 0; i < totalTiles; i++) {
      tiles.push({
        id: `tile-${i}`,
        originalIndex: i,
        currentIndex: i,
        imageUrl: this.imageUrl,
        isCorrect: true
      });
    }
    
    // Shuffle tiles (except the last one which stays in place)
    for (let i = tiles.length - 2; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [tiles[i].currentIndex, tiles[j].currentIndex] = [tiles[j].currentIndex, tiles[i].currentIndex];
      tiles[i].isCorrect = tiles[i].currentIndex === tiles[i].originalIndex;
      tiles[j].isCorrect = tiles[j].currentIndex === tiles[j].originalIndex;
    }
    
    return tiles;
  }

  private selectTile(tileId: string): void {
    if (this.state.status !== GameStatus.PLAYING) return;
    
    this.gameState.selectedTile = tileId;
    this.updateTime();
  }

  private swapTiles(tile1Id: string, tile2Id: string): void {
    if (this.state.status !== GameStatus.PLAYING) return;
    
    const tile1 = this.gameState.tiles.find(t => t.id === tile1Id);
    const tile2 = this.gameState.tiles.find(t => t.id === tile2Id);
    
    if (!tile1 || !tile2) return;
    
    // Swap current indices
    [tile1.currentIndex, tile2.currentIndex] = [tile2.currentIndex, tile1.currentIndex];
    
    // Update correctness
    tile1.isCorrect = tile1.currentIndex === tile1.originalIndex;
    tile2.isCorrect = tile2.currentIndex === tile2.originalIndex;
    
    this.gameState.moves++;
    this.gameState.selectedTile = null;
    
    // Check if puzzle is complete
    this.checkCompletion();
    
    this.updateTime();
  }

  private checkCompletion(): void {
    const isComplete = this.gameState.tiles.every(tile => tile.isCorrect);
    if (isComplete) {
      this.gameState.isComplete = true;
      this.state.status = GameStatus.COMPLETED;
      this.end();
    }
  }

  private calculatePuzzleScore(): number {
    if (!this.gameState.isComplete) return 0;
    
    const baseScore = 1000;
    const timeBonus = Math.max(0, 300 - Math.floor(this.getElapsedTime() / 1000)) * 2;
    const movePenalty = this.gameState.moves * 10;
    
    return Math.max(100, baseScore + timeBonus - movePenalty);
  }

  getPuzzleState(): ImagePuzzleGameState {
    return this.gameState;
  }

  createGameComponent(): React.FC {
    return () => <ImagePuzzleGameComponent />;
  }
}

export class ImagePuzzleGameFactory implements GameFactory {
  createGame(): BaseGame {
    return new ImagePuzzleGame();
  }

  getGameInfo() {
    return {
      id: 'image-puzzle',
      name: 'פאזל תמונה',
      description: 'סדר את חלקי התמונה למקומם הנכון',
      category: 'puzzle',
      thumbnail: '🧩',
      version: '1.0.0'
    };
  }
}

const { width: screenWidth } = Dimensions.get('window');

export const ImagePuzzleGameComponent: React.FC<ImagePuzzleGameProps> = ({
  gridSize = 3,
  difficulty = 'easy',
  imageUrl = 'https://picsum.photos/300/300',
  onGameComplete,
  onGameStart,
  onMove,
  showMenu = true,
  autoStart = false,
  title = '🧩 פאזל תמונה',
  subtitle = 'סדר את חלקי התמונה למקומם הנכון!',
  showStats = true,
  enableHints = true,
  enableReset = true,
  theme = {
    primaryColor: '#3498db',
    secondaryColor: '#2ecc71',
    backgroundColor: '#f8f9fa',
    textColor: '#2c3e50'
  }
}) => {
  const [currentScreen, setCurrentScreen] = useState(showMenu ? 'menu' : 'game');
  const [gameInstance, setGameInstance] = useState<ImagePuzzleGame | null>(null);
  const [gameState, setGameState] = useState<ImagePuzzleGameState | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [selectedTile, setSelectedTile] = useState<string | null>(null);
  const [gameStats, setGameStats] = useState({
    moves: 0,
    time: 0,
    score: 0,
    isComplete: false,
  });

  useEffect(() => {
    if (autoStart && !showMenu) {
      startNewGame();
    }
  }, [autoStart, showMenu]);

  const startNewGame = async () => {
    setIsLoading(true);
    try {
      const game = new ImagePuzzleGame();
      
      let gameDifficulty: GameDifficulty;
      switch (difficulty) {
        case 'easy':
          gameDifficulty = GameDifficulty.EASY;
          break;
        case 'medium':
          gameDifficulty = GameDifficulty.MEDIUM;
          break;
        case 'hard':
          gameDifficulty = GameDifficulty.HARD;
          break;
        default:
          gameDifficulty = GameDifficulty.EASY;
      }

      await game.initialize({
        gameId: 'image-puzzle',
        gridSize,
        difficulty: gameDifficulty,
        imageUrl,
        customization: {
          theme: {
            name: 'default',
            colors: {
              primary: theme.primaryColor,
              secondary: theme.secondaryColor,
              background: theme.backgroundColor,
              text: theme.textColor,
            },
          },
        },
        rules: {}
      } as any);

      (game as any).on('gameComplete', (result: any) => {
        console.log('🏁 Image puzzle complete!', result);
        onGameComplete?.(result);
        
        if (showMenu) {
          Alert.alert(
            '🎉 כל הכבוד!',
            `השלמת את הפאזל!\n` +
              `מהלכים: ${result.moves}\n` +
              `זמן: ${Math.floor(result.timeSpent / 1000)}s\n` +
              `ניקוד: ${result.score}`,
            [
              { text: 'פאזל חדש', onPress: () => startNewGame() },
              { text: 'חזור לתפריט', onPress: () => setCurrentScreen('menu') },
            ],
          );
        }
      });

      (game as any).on('gameStarted', () => {
        console.log('🚀 Image puzzle started!');
        onGameStart?.();
      });

      setGameInstance(game);
      setGameState(game.getPuzzleState());
      
      await game.start();
      
      setIsLoading(false);
      setCurrentScreen('game');
      
    } catch (error) {
      console.error('❌ Failed to start image puzzle:', error);
      Alert.alert('שגיאה', 'נכשל בהתחלת הפאזל');
      setIsLoading(false);
    }
  };

  const handleTilePress = (tileId: string) => {
    if (!gameInstance || !gameState) return;
    
    if (selectedTile === null) {
      setSelectedTile(tileId);
      gameInstance.processPlayerAction({
        type: 'SELECT_TILE',
        payload: { tileId },
        timestamp: new Date()
      });
    } else if (selectedTile !== tileId) {
      gameInstance.processPlayerAction({
        type: 'SWAP_TILES',
        payload: { tile1Id: selectedTile, tile2Id: tileId },
        timestamp: new Date()
      });
      setSelectedTile(null);
      onMove?.({ tile1Id: selectedTile, tile2Id: tileId });
    } else {
      setSelectedTile(null);
    }
    
    setGameState(gameInstance.getPuzzleState());
    setGameStats({
      moves: gameInstance.getPuzzleState().moves,
      time: (gameInstance as any).getElapsedTime(),
      score: 0,
      isComplete: gameInstance.getPuzzleState().isComplete,
    });
  };

  const resetGame = () => {
    if (gameInstance) {
      gameInstance.restart();
      setGameState(gameInstance.getPuzzleState());
      setSelectedTile(null);
      setGameStats({
        moves: 0,
        time: 0,
        score: 0,
        isComplete: false,
      });
    }
  };

  const renderTile = (tile: ImageTile, index: number) => {
    const tileSize = (screenWidth - 80) / gridSize;
    const isSelected = selectedTile === tile.id;
    
    return (
      <TouchableOpacity
        key={tile.id}
        style={[
          styles.tile,
          {
            width: tileSize,
            height: tileSize,
            backgroundColor: isSelected ? theme.secondaryColor : theme.primaryColor,
            borderColor: isSelected ? theme.secondaryColor : theme.primaryColor,
          }
        ]}
        onPress={() => handleTilePress(tile.id)}
        disabled={gameState?.isComplete}
      >
        <Image
          source={{ uri: imageUrl }}
          style={[
            styles.tileImage,
            {
              width: tileSize - 4,
              height: tileSize - 4,
            }
          ]}
          resizeMode="cover"
        />
        {!tile.isCorrect && (
          <View style={styles.incorrectIndicator}>
            <Text style={styles.incorrectText}>❌</Text>
          </View>
        )}
      </TouchableOpacity>
    );
  };

  const renderPuzzleBoard = () => (
    <View style={styles.puzzleBoard}>
      <View style={[styles.grid, { gridTemplateColumns: `repeat(${gridSize}, 1fr)` }]}>
        {gameState?.tiles.map((tile, index) => renderTile(tile, index))}
      </View>
    </View>
  );

  const renderMenuScreen = () => (
    <SafeAreaView style={[styles.container, { backgroundColor: theme.backgroundColor }]}>
      <StatusBar barStyle="dark-content" backgroundColor={theme.backgroundColor} />
      
      <View style={styles.menuContent}>
        <Text style={[styles.title, { color: theme.textColor }]}>{title}</Text>
        <Text style={[styles.subtitle, { color: theme.textColor }]}>{subtitle}</Text>
        
        <View style={styles.menuButtons}>
          <TouchableOpacity
            style={[styles.button, { backgroundColor: theme.primaryColor }]}
            onPress={startNewGame}
            disabled={isLoading}
          >
            <Text style={styles.buttonText}>
              {isLoading ? 'טוען...' : 'התחל פאזל'}
            </Text>
          </TouchableOpacity>
        </View>
        
        <View style={styles.gameInfo}>
          <Text style={[styles.infoText, { color: theme.textColor }]}>
            גודל רשת: {gridSize}x{gridSize}
          </Text>
          <Text style={[styles.infoText, { color: theme.textColor }]}>
            רמת קושי: {difficulty}
          </Text>
        </View>
      </View>
    </SafeAreaView>
  );

  const renderGameScreen = () => (
    <SafeAreaView style={[styles.container, { backgroundColor: theme.backgroundColor }]}>
      <StatusBar barStyle="dark-content" backgroundColor={theme.backgroundColor} />
      
      <View style={styles.gameContent}>
        <View style={styles.header}>
          <Text style={[styles.gameTitle, { color: theme.textColor }]}>פאזל תמונה</Text>
          {showStats && (
            <View style={styles.stats}>
              <Text style={[styles.statText, { color: theme.textColor }]}>
                מהלכים: {gameStats.moves}
              </Text>
              <Text style={[styles.statText, { color: theme.textColor }]}>
                זמן: {Math.floor(gameStats.time / 1000)}s
              </Text>
            </View>
          )}
        </View>
        
        {renderPuzzleBoard()}
        
        <View style={styles.controls}>
          {enableReset && (
            <TouchableOpacity
              style={[styles.controlButton, { backgroundColor: theme.secondaryColor }]}
              onPress={resetGame}
            >
              <Text style={styles.buttonText}>אפס משחק</Text>
            </TouchableOpacity>
          )}
          
          {showMenu && (
            <TouchableOpacity
              style={[styles.controlButton, { backgroundColor: theme.primaryColor }]}
              onPress={() => setCurrentScreen('menu')}
            >
              <Text style={styles.buttonText}>חזור לתפריט</Text>
            </TouchableOpacity>
          )}
        </View>
      </View>
    </SafeAreaView>
  );

  return currentScreen === 'menu' ? renderMenuScreen() : renderGameScreen();
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  menuContent: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  title: {
    fontSize: 28,
    fontWeight: 'bold',
    marginBottom: 10,
    textAlign: 'center',
  },
  subtitle: {
    fontSize: 16,
    marginBottom: 30,
    textAlign: 'center',
    opacity: 0.8,
  },
  menuButtons: {
    width: '100%',
    marginBottom: 30,
  },
  button: {
    padding: 15,
    borderRadius: 10,
    alignItems: 'center',
    marginVertical: 5,
  },
  buttonText: {
    color: 'white',
    fontSize: 16,
    fontWeight: 'bold',
  },
  gameInfo: {
    width: '100%',
  },
  infoText: {
    fontSize: 14,
    marginVertical: 2,
    textAlign: 'center',
  },
  gameContent: {
    flex: 1,
    padding: 20,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 20,
  },
  gameTitle: {
    fontSize: 24,
    fontWeight: 'bold',
  },
  stats: {
    alignItems: 'flex-end',
  },
  statText: {
    fontSize: 14,
    marginVertical: 2,
  },
  puzzleBoard: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  grid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',
    alignItems: 'center',
  },
  tile: {
    margin: 2,
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center',
    borderWidth: 2,
  },
  tileImage: {
    borderRadius: 6,
  },
  incorrectIndicator: {
    position: 'absolute',
    top: 2,
    right: 2,
  },
  incorrectText: {
    fontSize: 12,
  },
  controls: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    marginTop: 20,
  },
  controlButton: {
    padding: 10,
    borderRadius: 8,
    minWidth: 100,
    alignItems: 'center',
  },
}); 