import 'package:flame/components.dart';
import 'package:flutter/material.dart';
import 'package:shitman/game/components/vision_cone.dart';
import 'package:shitman/game/components/base.dart';
import 'package:shitman/settings/app_settings.dart';
import 'dart:math';

class Neighborhood extends DecorativeShit with Stationary, AppSettings {
  static const double streetWidth = 60.0;
  static const double houseSize = 80.0;
  static const double yardSize = 40.0;

  List<House> houses = [];
  late List<Vector2> streetPaths;

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    await initSettings();
    generateNeighborhood();
    appLog.fine('Neighborhood loaded with ${houses.length} houses');
  }

  void generateNeighborhood() {
    houses.clear();
    removeAll(children);

    // Create a simple 3x3 grid of houses
    final random = Random();

    for (int row = 0; row < 3; row++) {
      for (int col = 0; col < 3; col++) {
        // Skip center for street intersection
        if (row == 1 && col == 1) continue;

        final housePosition = Vector2(
          col * (houseSize + streetWidth) + streetWidth,
          row * (houseSize + streetWidth) + streetWidth,
        );

        final house = House(
          position: housePosition,
          isTarget: false, // Target will be set separately
          houseType: random.nextInt(3), // 3 different house types
        );

        houses.add(house);
        add(house);
      }
    }

    // Generate street paths
    generateStreetPaths();
  }

  void generateStreetPaths() {
    streetPaths = [];

    // Horizontal streets
    for (int i = 0; i < 4; i++) {
      streetPaths.add(Vector2(0, i * (houseSize + streetWidth)));
      streetPaths.add(Vector2(800, i * (houseSize + streetWidth)));
    }

    // Vertical streets
    for (int i = 0; i < 4; i++) {
      streetPaths.add(Vector2(i * (houseSize + streetWidth), 0));
      streetPaths.add(Vector2(i * (houseSize + streetWidth), 600));
    }
  }

  House? getRandomHouse() {
    if (houses.isEmpty) return null;
    final random = Random();
    return houses[random.nextInt(houses.length)];
  }

  @override
  void render(Canvas canvas) {
    // Draw streets
    final streetPaint = Paint()..color = const Color(0xFF333333);

    // Horizontal streets
    for (int row = 0; row <= 3; row++) {
      canvas.drawRect(
        Rect.fromLTWH(
          0,
          row * (houseSize + streetWidth) - streetWidth / 2,
          800,
          streetWidth,
        ),
        streetPaint,
      );
    }

    // Vertical streets
    for (int col = 0; col <= 3; col++) {
      canvas.drawRect(
        Rect.fromLTWH(
          col * (houseSize + streetWidth) - streetWidth / 2,
          0,
          streetWidth,
          600,
        ),
        streetPaint,
      );
    }
  }

  @override
  Future<void> reset() async {
    appLog.fine('Resetting neighborhood');
    
    // Reset all houses
    for (final house in houses) {
      await house.reset();
    }
    
    // Regenerate neighborhood if needed
    generateNeighborhood();
  }
}

class House extends DecorativeShit with Stationary, AppSettings {
  bool isTarget;
  int houseType;
  bool hasLights = false;
  bool hasSecurityCamera = false;
  bool hasWatchDog = false;

  Vector2? doorPosition;
  Vector2? yardCenter;
  VisionCone? visionCone;

  House({
    required Vector2 position,
    required this.isTarget,
    required this.houseType,
  }) {
    this.position = position;
    size = Vector2.all(Neighborhood.houseSize);
  }

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    await initSettings();

    // Calculate door and yard positions
    doorPosition = position + Vector2(size.x / 2, size.y);
    yardCenter = position + size / 2;

    // Randomly add security features
    final random = Random();
    hasLights = random.nextBool();
    hasSecurityCamera = random.nextDouble() < 0.3;
    hasWatchDog = random.nextDouble() < 0.2;

    // Create vision cone for houses with security cameras
    if (hasSecurityCamera) {
      _createVisionCone();
    }

    appLog.fine('House loaded at $position (type: $houseType, target: $isTarget)');
  }

  void _createVisionCone() {
    // Create vision cone facing towards the street
    final cameraPosition = Vector2(size.x * 0.9, size.y * 0.1);
    final direction = _getOptimalCameraDirection();

    visionCone = VisionCone(
      origin: cameraPosition,
      direction: direction,
      range: 120.0,
      fov: pi / 2, // 90 degrees
      color: Colors.red,
      opacity: 0.2,
    );
    add(visionCone!);
  }

  double _getOptimalCameraDirection() {
    // Point camera towards street/center area
    final centerOfMap = Vector2(400, 300);
    final houseCenter = position + size / 2;
    final toCenter = centerOfMap - houseCenter;
    return atan2(toCenter.y, toCenter.x);
  }

  Color _getHouseColor() {
    switch (houseType) {
      case 0:
        return isTarget
            ? const Color(0xFFFF6B6B)
            : const Color(0xFF8B4513); // Brown/Red if target
      case 1:
        return isTarget
            ? const Color(0xFFFF6B6B)
            : const Color(0xFF4682B4); // Blue/Red if target
      case 2:
        return isTarget
            ? const Color(0xFFFF6B6B)
            : const Color(0xFF228B22); // Green/Red if target
      default:
        return const Color(0xFF696969);
    }
  }

  @override
  void render(Canvas canvas) {
    // Draw house with color based on type and target status
    final housePaint = Paint()..color = _getHouseColor();
    canvas.drawRect(size.toRect(), housePaint);

    // Draw door
    final doorPaint = Paint()..color = const Color(0xFF654321);
    canvas.drawRect(
      Rect.fromLTWH(size.x / 2 - 8, size.y - 4, 16, 4),
      doorPaint,
    );

    // Draw windows
    final windowPaint = Paint()
      ..color = hasLights ? const Color(0xFFFFFF00) : const Color(0xFF87CEEB);

    // Left window
    canvas.drawRect(
      Rect.fromLTWH(size.x * 0.2, size.y * 0.3, 12, 12),
      windowPaint,
    );

    // Right window
    canvas.drawRect(
      Rect.fromLTWH(size.x * 0.7, size.y * 0.3, 12, 12),
      windowPaint,
    );

    // Draw security features
    if (hasSecurityCamera) {
      final cameraPaint = Paint()..color = const Color(0xFF000000);
      canvas.drawCircle(Offset(size.x * 0.9, size.y * 0.1), 4, cameraPaint);
    }

    if (hasWatchDog) {
      // Draw dog house in yard
      final dogHousePaint = Paint()..color = const Color(0xFF8B4513);
      canvas.drawRect(Rect.fromLTWH(-20, size.y + 10, 15, 15), dogHousePaint);
    }

    // Draw detection radius if setting is enabled
    try {
      if (appSettings.getBool('game.show_detection_radius')) {
        final radiusPaint = Paint()
          ..color = const Color(0xFFFF9800).withValues(alpha: 0.2)
          ..style = PaintingStyle.stroke
          ..strokeWidth = 2.0;
        canvas.drawCircle(
          Offset(size.x / 2, size.y / 2),
          getDetectionRadius(),
          radiusPaint,
        );
      }
    } catch (e) {
      // Settings not ready, skip rendering
    }

    // Draw target indicator
    if (isTarget) {
      final targetPaint = Paint()
        ..color = const Color(0xFFFF0000)
        ..style = PaintingStyle.stroke
        ..strokeWidth = 3.0;
      canvas.drawCircle(
        Offset(size.x / 2, size.y / 2),
        size.x / 2 + 10,
        targetPaint,
      );
    }
  }

  double getDetectionRadius() {
    double radius = 30.0; // Reduced base radius
    if (hasLights) radius += 10.0; // Reduced light bonus
    if (hasSecurityCamera) radius += 20.0; // Reduced camera bonus
    if (hasWatchDog) radius += 15.0; // Reduced dog bonus
    return radius;
  }

  bool canDetectPlayer(Vector2 playerPosition, double playerStealthLevel) {
    // Basic radius detection
    final distance = (playerPosition - yardCenter!).length;
    final detectionRadius = getDetectionRadius() * (1.0 - playerStealthLevel);

    bool radiusDetection = distance < detectionRadius;

    // Vision cone detection for security cameras
    bool visionDetection = false;
    if (hasSecurityCamera && visionCone != null) {
      visionDetection =
          visionCone!.canSee(playerPosition) &&
          visionCone!.hasLineOfSight(playerPosition, []);
    }

    return radiusDetection || visionDetection;
  }

  @override
  void update(double dt) {
    super.update(dt);

    // Update vision cone visibility based on settings
    if (visionCone != null) {
      try {
        final showVisionCones = appSettings.getBool('game.show_vision_cones');
        visionCone!.updateOpacity(showVisionCones ? 0.3 : 0.0);
      } catch (e) {
        visionCone!.updateOpacity(0.0); // Hide if settings not ready
      }
    }
  }

  @override
  Future<void> reset() async {
    isTarget = false;
    hasLights = false;
    hasSecurityCamera = false;
    hasWatchDog = false;
    
    // Reset vision cone
    if (visionCone != null) {
      await visionCone!.reset();
      removeAll(children.whereType<VisionCone>());
      visionCone = null;
    }
    
    // Regenerate security features
    final random = Random();
    hasLights = random.nextBool();
    hasSecurityCamera = random.nextDouble() < 0.3;
    hasWatchDog = random.nextDouble() < 0.2;
    
    // Recreate vision cone if needed
    if (hasSecurityCamera) {
      _createVisionCone();
    }
    
    appLog.fine('House reset at $position');
  }
}
