import 'package:flame/components.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:shitman/game/shitman_game.dart';
import 'package:shitman/game/components/poop_bag.dart';
import 'package:shitman/game/components/neighborhood.dart';
import 'package:shitman/game/components/vision_cone.dart';
import 'dart:math';

class Player extends RectangleComponent with HasGameReference<ShitmanGame> {
  static const double speed = 100.0;
  static const double playerSize = 32.0;

  Vector2 velocity = Vector2.zero();
  bool hasPoopBag = true;
  bool isHidden = false;
  double stealthLevel = 0.0; // 0.0 = fully visible, 1.0 = completely hidden
  PoopBag? placedPoopBag;
  VisionCone? playerVisionCone;
  double lastMovementDirection = 0.0;

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

    // Create a simple colored rectangle as player
    size = Vector2.all(playerSize);
    position = Vector2(200, 200); // Start at center intersection

    // Set player color
    paint = Paint()..color = const Color(0xFF0000FF); // Blue player

    // Create player vision cone
    playerVisionCone = VisionCone(
      origin: size / 2, // Relative to player center
      direction: lastMovementDirection,
      range: 80.0,
      fov: pi / 2, // 90 degrees
      color: Colors.blue,
      opacity: 0.0, // Start hidden
    );
    add(playerVisionCone!);
  }

  void handleInput(Set<LogicalKeyboardKey> keysPressed) {
    velocity = Vector2.zero();

    // Movement controls
    if (keysPressed.contains(LogicalKeyboardKey.arrowUp) ||
        keysPressed.contains(LogicalKeyboardKey.keyW)) {
      velocity.y -= speed;
    }
    if (keysPressed.contains(LogicalKeyboardKey.arrowDown) ||
        keysPressed.contains(LogicalKeyboardKey.keyS)) {
      velocity.y += speed;
    }
    if (keysPressed.contains(LogicalKeyboardKey.arrowLeft) ||
        keysPressed.contains(LogicalKeyboardKey.keyA)) {
      velocity.x -= speed;
    }
    if (keysPressed.contains(LogicalKeyboardKey.arrowRight) ||
        keysPressed.contains(LogicalKeyboardKey.keyD)) {
      velocity.x += speed;
    }
  }

  void handleAction(LogicalKeyboardKey key) {
    // Action controls
    if (key == LogicalKeyboardKey.space) {
      placePoop();
    }
    if (key == LogicalKeyboardKey.keyE) {
      ringDoorbell();
    }
  }

  void updateStealthLevel(double dt) {
    // Simple stealth calculation - can be enhanced later
    // For now, player is more hidden when moving slowly or not at all
    if (velocity.length < 50) {
      stealthLevel = (stealthLevel + dt * 0.5).clamp(0.0, 1.0);
    } else {
      stealthLevel = (stealthLevel - dt * 1.5).clamp(0.0, 1.0);
    }

    isHidden = stealthLevel > 0.7;
  }

  void placePoop() {
    if (!hasPoopBag) return;

    debugPrint('Placing poop bag at $position');

    // Create and place the poop bag
    placedPoopBag = PoopBag();
    placedPoopBag!.position =
        position + Vector2(playerSize / 2, playerSize + 10);
    game.world.add(placedPoopBag!);

    hasPoopBag = false;

    // Check if near target house
    checkMissionProgress();
  }

  void ringDoorbell() {
    debugPrint('Attempting to ring doorbell');

    // Check if near target house door
    if (game.targetHouse.isPlayerNearTarget(position)) {
      if (placedPoopBag != null) {
        // Light the poop bag on fire
        placedPoopBag!.lightOnFire();
        debugPrint('Ding dong! Poop bag is lit! RUN!');

        // Start escape timer - player has limited time to escape
        startEscapeSequence();
      } else {
        debugPrint('Need to place poop bag first!');
      }
    } else {
      debugPrint('Not near target house door');
    }
  }

  void startEscapeSequence() {
    // TODO: Implement escape mechanics
    // For now, automatically complete mission after a delay
    Future.delayed(Duration(seconds: 3), () {
      if (game.gameState == GameState.playing) {
        game.completeCurrentMission();
      }
    });
  }

  void checkMissionProgress() {
    // Check if near target house and has placed poop bag
    final targetPos = game.targetHouse.getTargetPosition();
    if (targetPos != null && placedPoopBag != null) {
      final distance = (position - targetPos).length;
      if (distance < 80) {
        debugPrint('Near target house with poop bag placed!');
      }
    }
  }

  void getDetected() {
    debugPrint('Player detected! Mission failed!');
    game.failMission();
  }

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

    // Apply movement
    if (velocity.length > 0) {
      velocity = velocity.normalized() * speed;
      position += velocity * dt;

      // Update movement direction for vision cone
      lastMovementDirection = atan2(velocity.y, velocity.x);

      // Keep player on screen (basic bounds checking)
      position.x = position.x.clamp(0, 800 - size.x);
      position.y = position.y.clamp(0, 600 - size.y);
    }

    // Update stealth level based on environment
    updateStealthLevel(dt);

    // Check for detection by houses
    checkForDetection();

    // Update player vision cone
    if (playerVisionCone != null) {
      playerVisionCone!.updatePosition(size / 2, lastMovementDirection);

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

  void checkForDetection() {
    final neighborhood =
        game.world.children.whereType<Neighborhood>().firstOrNull;
    if (neighborhood == null) return;

    for (final house in neighborhood.houses) {
      if (house.canDetectPlayer(position, stealthLevel)) {
        getDetected();
        break;
      }
    }
  }

  @override
  void render(Canvas canvas) {
    // Update paint color based on stealth level
    paint =
        Paint()
          ..color =
              isHidden
                  ? const Color(0xFF00FF00).withValues(alpha: 0.7)
                  : // Green when hidden
                  const Color(
                    0xFF0000FF,
                  ).withValues(alpha: 0.9); // Blue when visible

    super.render(canvas);

    // Draw stealth indicator in debug mode
    if (game.debugMode) {
      final stealthPaint =
          Paint()
            ..color =
                Color.lerp(
                  const Color(0xFFFF0000),
                  const Color(0xFF00FF00),
                  stealthLevel,
                )!;
      canvas.drawRect(Rect.fromLTWH(-5, -10, size.x + 10, 5), stealthPaint);
    }
  }
}
