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

/// PIR sensor triggered light
class PIRSensorComponent extends SecurityComponent with AppSettings {
  bool isTriggered = false;
  bool lightsOn = false;
  bool _showDetectionRadius = true;
  
  PIRSensorComponent({
    required super.position,
    super.detectionRange = 40.0,
  }) {
    size = Vector2(8, 8);
  }

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    await initSettings();
    
    // Initialize detection radius visibility from settings
    try {
      _showDetectionRadius = appSettings.getBool('game.show_detection_radius');
    } catch (e) {
      _showDetectionRadius = true; // Default to visible
    }
  }

  @override
  bool detectsPlayer(Vector2 playerPosition, double playerStealthLevel) {
    final distance = (playerPosition - position).length;
    final effectiveRange = getEffectiveDetectionRange(playerStealthLevel);
    
    bool detected = distance < effectiveRange;
    
    if (detected && !isTriggered) {
      isTriggered = true;
      lightsOn = true;
      appLog.fine('PIR sensor triggered at $position');
    } else if (!detected && isTriggered) {
      // Cool down period before turning off
      Future.delayed(const Duration(seconds: 5), () {
        isTriggered = false;
        lightsOn = false;
      });
    }
    
    return detected;
  }

  @override
  void render(Canvas canvas) {
    // Draw detection radius if enabled
    if (_showDetectionRadius) {
      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),
        detectionRange,
        radiusPaint,
      );
    }
    
    // Draw PIR sensor as small circle
    final sensorPaint = Paint()
      ..color = isTriggered ? const Color(0xFFFF0000) : const Color(0xFF000000);
    canvas.drawCircle(Offset(size.x / 2, size.y / 2), 4, sensorPaint);
    
    // Draw light effect if triggered
    if (lightsOn) {
      final lightPaint = Paint()
        ..color = const Color(0xFFFFFF00).withValues(alpha: 0.3);
      canvas.drawCircle(
        Offset(size.x / 2, size.y / 2),
        detectionRange,
        lightPaint,
      );
    }
  }
  
  /// Update detection radius visibility (call when settings change)
  void updateDetectionRadiusVisibility(bool visible) {
    _showDetectionRadius = visible;
  }
  
  /// Refresh visibility from current settings
  void refreshVisibilityFromSettings() {
    try {
      final newVisibility = appSettings.getBool('game.show_detection_radius');
      updateDetectionRadiusVisibility(newVisibility);
    } catch (e) {
      // Settings not ready, keep current state
    }
  }
  
  @override
  Future<void> reset() async {
    isTriggered = false;
    lightsOn = false;
  }
}

/// Security camera with vision cone
class SecurityCameraComponent extends SecurityComponent with AppSettings {
  late VisionCone visionCone;
  double direction;
  bool _currentVisionConeVisibility = true;
  
  SecurityCameraComponent({
    required super.position,
    required this.direction,
    super.detectionRange = 120.0,
  }) {
    size = Vector2(8, 8);
  }

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    await initSettings();
    
    // Create vision cone with initial visibility based on settings
    try {
      _currentVisionConeVisibility = appSettings.getBool('game.show_vision_cones');
    } catch (e) {
      _currentVisionConeVisibility = true; // Default to visible
    }
    
    visionCone = VisionCone(
      origin: Vector2.zero(),
      direction: direction,
      range: detectionRange,
      fov: pi / 2, // 90 degrees
      color: Colors.red,
      opacity: _currentVisionConeVisibility ? 0.3 : 0.0,
    );
    add(visionCone);
  }

  @override
  bool detectsPlayer(Vector2 playerPosition, double playerStealthLevel) {
    return visionCone.canSee(playerPosition) &&
           visionCone.hasLineOfSight(playerPosition, []);
  }

  @override
  void render(Canvas canvas) {
    // Draw camera as black circle
    final cameraPaint = Paint()..color = const Color(0xFF000000);
    canvas.drawCircle(Offset(size.x / 2, size.y / 2), 4, cameraPaint);
  }
  
  /// Call this method when settings change to update vision cone visibility
  void updateVisionConeVisibility(bool visible) {
    if (_currentVisionConeVisibility != visible) {
      _currentVisionConeVisibility = visible;
      visionCone.updateOpacity(visible ? 0.3 : 0.0);
    }
  }
  
  /// Refresh visibility from current settings (call when settings might have changed)
  void refreshVisibilityFromSettings() {
    try {
      final newVisibility = appSettings.getBool('game.show_vision_cones');
      updateVisionConeVisibility(newVisibility);
    } catch (e) {
      // Settings not ready, keep current state
    }
  }
  
  @override
  Future<void> reset() async {
    await visionCone.reset();
  }
}

/// Guard dog with patrol area
class GuardDogComponent extends SecurityComponent with AppSettings {
  Vector2 patrolCenter;
  double patrolRadius;
  double currentAngle = 0;
  bool isPatrolling = true;
  bool _showDetectionRadius = true;
  
  GuardDogComponent({
    required super.position,
    required this.patrolCenter,
    this.patrolRadius = 30.0,
    super.detectionRange = 50.0,
  }) {
    size = Vector2(12, 12);
  }

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    await initSettings();
    
    // Initialize detection radius visibility from settings
    try {
      _showDetectionRadius = appSettings.getBool('game.show_detection_radius');
    } catch (e) {
      _showDetectionRadius = true; // Default to visible
    }
  }

  @override
  bool detectsPlayer(Vector2 playerPosition, double playerStealthLevel) {
    final distance = (playerPosition - position).length;
    final effectiveRange = getEffectiveDetectionRange(playerStealthLevel);
    
    return distance < effectiveRange;
  }

  @override
  void update(double dt) {
    super.update(dt);
    
    if (isPatrolling) {
      // Simple circular patrol
      currentAngle += dt * 0.5; // Rotation speed
      final offset = Vector2(
        cos(currentAngle) * patrolRadius,
        sin(currentAngle) * patrolRadius,
      );
      position = patrolCenter + offset;
    }
  }

  @override
  void render(Canvas canvas) {
    // Draw detection radius if enabled
    if (_showDetectionRadius) {
      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),
        detectionRange,
        radiusPaint,
      );
    }
    
    // Draw dog house
    final dogHousePaint = Paint()..color = const Color(0xFF8B4513);
    canvas.drawRect(
      Rect.fromLTWH(0, 0, size.x, size.y),
      dogHousePaint,
    );
    
    // Draw dog (simple circle)
    final dogPaint = Paint()..color = const Color(0xFF654321);
    canvas.drawCircle(
      Offset(size.x / 2, size.y / 2),
      4,
      dogPaint,
    );
  }
  
  void stopPatrol() {
    isPatrolling = false;
  }
  
  void startPatrol() {
    isPatrolling = true;
  }
  
  /// Update detection radius visibility (call when settings change)
  void updateDetectionRadiusVisibility(bool visible) {
    _showDetectionRadius = visible;
  }
  
  /// Refresh visibility from current settings
  void refreshVisibilityFromSettings() {
    try {
      final newVisibility = appSettings.getBool('game.show_detection_radius');
      updateDetectionRadiusVisibility(newVisibility);
    } catch (e) {
      // Settings not ready, keep current state
    }
  }
  
  @override
  Future<void> reset() async {
    currentAngle = 0;
    isPatrolling = true;
    position = patrolCenter;
  }
}