import 'package:flame/components.dart';
import 'package:shitman/game/levels/shit_level.dart';
import 'package:shitman/game/components/level_components.dart';
import 'package:shitman/game/components/road_components.dart';
import 'package:shitman/game/components/house_components.dart';
import 'package:shitman/game/components/security_components.dart';
import 'dart:math';

/// Level 1: Operation Shitstorm
/// A grid-based neighborhood with various house types and security systems
class OperationShitstorm extends ShitLevel {
  static const double cellSize = 100.0;
  static const int gridWidth = 5;
  static const int gridHeight = 5;
  
  List<List<LevelComponent?>> levelGrid = [];
  List<HouseComponent> houses = [];
  TargetHouseComponent? currentTarget;
  
  OperationShitstorm() : super(levelName: "Operation: Shitstorm", difficulty: 1);

  @override
  Future<void> initializeLevelComponents() async {
    appLog.fine('Initializing Operation Shitstorm level layout');
    
    // Initialize the grid
    levelGrid = List.generate(
      gridHeight,
      (row) => List.generate(gridWidth, (col) => null),
    );
    
    // Create the level layout
    await createLevelLayout();
    
    // Add all components to the level
    await addComponentsToLevel();
    
    // Initialize core components (player, etc.)
    await super.initializeLevelComponents();
    
    // Select a random target house
    selectRandomTarget();
    
    appLog.fine('Operation Shitstorm level initialized');
  }
  
  Future<void> createLevelLayout() async {
    // Create a simple grid layout:
    // H = House, R = Road (various types), I = Intersection
    // Layout pattern:
    // H R H R H
    // R I R I R  
    // H R H R H
    // R I R I R
    // H R H R H
    
    for (int row = 0; row < gridHeight; row++) {
      for (int col = 0; col < gridWidth; col++) {
        final gridPos = Vector2(col.toDouble(), row.toDouble());
        
        if (row % 2 == 0) { // Even rows: Houses and vertical roads
          if (col % 2 == 0) {
            // House position
            levelGrid[row][col] = createRandomHouse(gridPos);
          } else {
            // Vertical road
            levelGrid[row][col] = VerticalRoad(gridPosition: gridPos);
          }
        } else { // Odd rows: Horizontal roads and intersections
          if (col % 2 == 0) {
            // Horizontal road
            levelGrid[row][col] = HorizontalRoad(gridPosition: gridPos);
          } else {
            // Intersection
            levelGrid[row][col] = IntersectionRoad(gridPosition: gridPos);
          }
        }
      }
    }
  }
  
  HouseComponent createRandomHouse(Vector2 gridPos) {
    final random = Random();
    final houseTypes = HouseType.values;
    final selectedType = houseTypes[random.nextInt(houseTypes.length)];
    
    final house = HouseComponent(
      gridPosition: gridPos,
      houseType: selectedType,
    );
    
    // Randomly add security systems to some houses
    if (random.nextDouble() < 0.4) { // 40% chance of security
      addRandomSecurityToHouse(house, random);
    }
    
    houses.add(house);
    return house;
  }
  
  void addRandomSecurityToHouse(HouseComponent house, Random random) {
    final securityTypes = random.nextInt(3); // 0-2 different security types
    
    switch (securityTypes) {
      case 0:
        // PIR sensor
        final pirSensor = PIRSensorComponent(
          position: Vector2(house.size.x * 0.9, house.size.y * 0.1),
        );
        house.addSecuritySystem(pirSensor);
        break;
      case 1:
        // Security camera
        final camera = SecurityCameraComponent(
          position: Vector2(house.size.x * 0.9, house.size.y * 0.1),
          direction: _getOptimalCameraDirection(house),
        );
        house.addSecuritySystem(camera);
        break;
      case 2:
        // Guard dog
        final dog = GuardDogComponent(
          position: Vector2(-20, house.size.y + 10),
          patrolCenter: Vector2(-20, house.size.y + 10),
        );
        house.addSecuritySystem(dog);
        break;
    }
  }
  
  double _getOptimalCameraDirection(HouseComponent house) {
    // Point camera towards center of level
    final levelCenter = Vector2(gridWidth * cellSize / 2, gridHeight * cellSize / 2);
    final houseCenter = house.getWorldPosition(cellSize) + house.size / 2;
    final toCenter = levelCenter - houseCenter;
    return atan2(toCenter.y, toCenter.x);
  }
  
  Future<void> addComponentsToLevel() async {
    for (int row = 0; row < gridHeight; row++) {
      for (int col = 0; col < gridWidth; col++) {
        final component = levelGrid[row][col];
        if (component != null) {
          // Set world position based on grid position
          component.position = component.getWorldPosition(cellSize);
          add(component);
        }
      }
    }
  }
  
  void selectRandomTarget() {
    if (houses.isEmpty) return;
    
    // Clear previous target
    currentTarget?.setAsTarget(false);
    
    // Convert a random house to a target house
    final random = Random();
    final randomHouse = houses[random.nextInt(houses.length)];
    
    // Remove the old house and create a new target house at the same position
    remove(randomHouse);
    houses.remove(randomHouse);
    
    currentTarget = TargetHouseComponent(
      gridPosition: randomHouse.gridPosition,
      houseType: randomHouse.houseType,
    );
    currentTarget!.position = randomHouse.position;
    currentTarget!.setAsTarget(true);
    
    // Copy security systems
    for (final security in randomHouse.securitySystems) {
      currentTarget!.addSecuritySystem(security);
    }
    
    add(currentTarget!);
    houses.add(currentTarget!);
    
    appLog.info('Target selected at grid position ${currentTarget!.gridPosition}');
  }
  
  @override
  Future<void> onLevelStart() async {
    appLog.info('Starting Operation: Shitstorm');
    // Level-specific start logic can be added here
  }
  
  @override
  Future<void> onLevelEnd() async {
    appLog.info('Operation: Shitstorm completed');
    // Level-specific end logic can be added here
  }
  
  @override
  Future<void> reset() async {
    await super.reset();
    
    // Clear level-specific data
    levelGrid.clear();
    houses.clear();
    currentTarget = null;
    
    // Recreate the level
    await createLevelLayout();
    await addComponentsToLevel();
    selectRandomTarget();
    
    appLog.fine('Operation Shitstorm level reset');
  }
  
  /// Get the current target house position
  Vector2? getTargetPosition() {
    return currentTarget?.doorPosition;
  }
  
  /// Check if player is near the target
  bool isPlayerNearTarget(Vector2 playerPosition, {double threshold = 50.0}) {
    final targetPos = getTargetPosition();
    if (targetPos == null) return false;
    
    final distance = (playerPosition - targetPos).length;
    return distance < threshold;
  }
}