using Cirno.Scripts.Components.Actors;
using Cirno.Scripts.Enums;
using Godot;

namespace Cirno.Scripts.Components.FSM.Enemy;

public partial class TurretAnimationModule : ModuleBase<EnemyState, CharacterBody2D>
{
    private IStateMachine<EnemyState, CharacterBody2D> _machine;
    [Export] public PlayerAnimationProvider AnimationProvider { get; set; }

    [Export] public EnemyStorageModule StorageModule { get; set; }
    [Export] public ActorResourceProvider HealthProvider { get; set; }

    [Export] public Vector2 TurretFacingDirection { get; set; } = Vector2.Down;
    [Export] public float SweepAngle = 90f; // In degrees
    [Export] public float SweepSpeed = 1f; // Speed of sweeping
    [Export] public bool Debug = false; // Enable debug lines
    //[Export] public NodePath SpritePath;

    private float _currentAngle;
    private float _sweepDirection = 1f;
    private float _raycastLength;

    public override void EnterState(EnemyState state)
    {
        //AnimationProvider.SetAnimation(StorageModule.AimingDirection);
        //AnimationProvider.SetAnimation(Vector2.Zero);
        if (HealthProvider is not null)
        {
            HealthProvider.ResourceDecreased += HealthProviderOnResourceDecreased;
        }
    }

    private void HealthProviderOnResourceDecreased(float oldValue, float newValue, float maxValue)
    {
        AnimationProvider?.Blink();
    }

    public override void ExitState(EnemyState state)
    {
        //AnimationProvider.SetAnimation(Vector2.Zero);
        if (HealthProvider is not null)
        {
            HealthProvider.ResourceDecreased -= HealthProviderOnResourceDecreased;
        }
    }

    public override void Init(IStateMachine<EnemyState, CharacterBody2D> machine)
    {
        _machine = machine;
    }

    public override void Process(double delta)
    {
        if (StorageModule.AimingDirection == Vector2.Zero || TurretFacingDirection == Vector2.Zero)
            return;

        // Calculate the angle between the turret's facing direction and the aim direction
        float angleToTarget = TurretFacingDirection.AngleTo(StorageModule.AimingDirection); // radians

        // Clamp the angle to within the sweep cone
        float halfSweepRad = Mathf.DegToRad(SweepAngle / 2f);
        float clampedAngle = Mathf.Clamp(angleToTarget, -halfSweepRad, halfSweepRad);

        // Convert to degrees before passing to SweepSprite
        float clampedAngleDeg = Mathf.RadToDeg(clampedAngle);
        // Update the sprite based on this clamped angle
        AnimationProvider.SweepSprite(clampedAngleDeg, SweepAngle);


        //AnimationProvider.SetAnimation(StorageModule.AimingDirection);
    }

    public override void PhysicsProcess(double delta)
    {
    }

    private void Sweep(float delta)
    {
        _currentAngle += _sweepDirection * SweepSpeed * delta;

        // Clamp angle within the sweep range
        float halfAngle = SweepAngle / 2f;
        if (_currentAngle > halfAngle || _currentAngle < -halfAngle)
        {
            _sweepDirection *= -1f;
            _currentAngle = Mathf.Clamp(_currentAngle, -halfAngle, halfAngle);
        }
    }

    // private void DrawDebugLine(Vector2 endPoint)
    // {
    //     // Request the node to redraw
    //     QueueRedraw();
    //     _debugLineEndPoint = endPoint;
    // }

    private void UpdateSpriteDirection()
    {
        AnimationProvider.SweepSprite(_currentAngle, SweepAngle);
    }

    private Vector2 _debugLineEndPoint;

    // public override void _Draw()
    // {
    //     if (Debug)
    //     {
    //         DrawLine(Vector2.Zero, ToLocal(_debugLineEndPoint), Colors.Red, 2);
    //     }
    // }
}