using Godot;
using SupaLidlGame.Extensions;

namespace SupaLidlGame.State.Thinker;

public partial class CenturionAttackState : BlockAttackState
{
    [Export]
    public bool FollowTeammate { get; set; } = false;

    [Export]
    public NavigationAgent2D NavigationAgent { get; set; }

    [Export]
    public float PathfindingDistance { get; set; } = 64;

    protected Characters.Character _bestTeammate = null;

    public Characters.Character FindBestTeammate()
    {
        float bestScore = float.MaxValue;
        Characters.Character bestChar = null;
        var world = this.GetWorld();

        foreach (Node node in world.CurrentMap.Entities.GetChildren())
        {
            if (node != NPC && node is Characters.Character character)
            {
                if (!IsInstanceValid(character) || !character.IsAlive)
                {
                    continue;
                }

                if (character.Faction == NPC.Faction)
                {
                    float score = NPC.Position.DistanceTo(character.Position);
                    if (score < bestScore)
                    {
                        bestScore = score;
                        bestChar = character;
                    }
                }
            }
        }

        return _bestTeammate = bestChar;
    }

    public override ThinkerState Think()
    {
        base.Think();

        if (_bestTarget?.StunTime > 0)
        {
            return null;
        }

        var teammate = FindBestTeammate();
        if (teammate is not null)
        {
            UpdateWeights(teammate.GlobalPosition);
            NavigationAgent.TargetPosition = teammate.GlobalPosition;
        }

        return null;
    }

    public override ThinkerState Process(double delta)
    {
        if (_bestTeammate is null)
        {
            return null;
        }

        float dist = NPC.DistanceTo(_bestTeammate);
        if (NPC.DistanceTo(_bestTeammate) < PathfindingDistance)
        {
            // move to weighted position
            return base.Process(delta);
        }
        return null;
    }

    public override ThinkerState PhysicsProcess(double delta)
    {
        if (_bestTeammate is not null)
        {
            float dist = NPC.DistanceTo(_bestTeammate);
            if (dist >= PathfindingDistance)
            {
                var nextPos = NavigationAgent.GetNextPathPosition();
                NPC.Direction = NPC.GlobalPosition.DirectionTo(nextPos);
            }
        }

        return base.PhysicsProcess(delta);
    }
}
