using FarseerPhysics;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Barotrauma
{
    partial class EnemyAIController : AIController
    {
        public override void DebugDraw(SpriteBatch spriteBatch)
        {
            if (Character.IsUnconscious || !Character.Enabled || !Enabled || Screen.Selected?.Cam is { Zoom: < 0.4f }) { return; }

            Vector2 pos = Character.DrawPosition;
            pos.Y = -pos.Y;

            if (State == AIState.Idle && PreviousState == AIState.Attack)
            {
                var target = _selectedAiTarget ?? _lastAiTarget;
                if (target != null && target.Entity != null)
                {
                    var memory = GetTargetMemory(target);
                    if (memory != null)
                    {
                        Vector2 targetPos = memory.Location;
                        targetPos.Y = -targetPos.Y;
                        GUI.DrawLine(spriteBatch, pos, targetPos, Color.White * 0.5f, 0, 4);
                        GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{target.Entity} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
                    }
                }
            }
            else if (SelectedAiTarget?.Entity != null)
            {
                Vector2 targetPos = SelectedAiTarget.Entity.DrawPosition;
                if (State == AIState.Attack)
                {
                    targetPos = attackWorldPos;
                }
                targetPos.Y = -targetPos.Y;

                GUI.DrawLine(spriteBatch, pos, targetPos, GUIStyle.Red * 0.5f, 0, 4);
                if (wallTarget != null && !IsCoolDownRunning)
                {
                    Vector2 wallTargetPos = wallTarget.Position;
                    if (wallTarget.Structure.Submarine != null) { wallTargetPos += wallTarget.Structure.Submarine.DrawPosition; }
                    wallTargetPos.Y = -wallTargetPos.Y;
                    GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
                    GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
                }
                GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity}", GUIStyle.Red, Color.Black);
                GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"{targetValue.FormatZeroDecimal()} (M: {CurrentTargetMemory?.Priority.FormatZeroDecimal()}, P: {CurrentTargetingParams?.Priority.FormatZeroDecimal()})", GUIStyle.Red, Color.Black);
            }

            /*GUIStyle.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, GUIStyle.Red);
            GUIStyle.Font.DrawString(spriteBatch, "updatetargets: " + MathUtils.Round(updateTargetsTimer, 0.1f), pos - Vector2.UnitY * 100.0f, GUIStyle.Red);
            GUIStyle.Font.DrawString(spriteBatch, "cooldown: " + MathUtils.Round(coolDownTimer, 0.1f), pos - Vector2.UnitY * 120.0f, GUIStyle.Red);*/

            Color stateColor = Color.White;
            switch (State)
            {
                case AIState.Attack:
                    stateColor = IsCoolDownRunning ? Color.Orange : GUIStyle.Red;
                    break;
                case AIState.Escape:
                    stateColor = Color.LightBlue;
                    break;
                case AIState.Flee:
                    stateColor = Color.White;
                    break;
                case AIState.Eat:
                    stateColor = Color.Brown;
                    break;
            }
            GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 80.0f, State.ToString(), stateColor, Color.Black);

            if (State == AIState.Attack && currentTargetingParams != null && currentTargetingParams.AttackPattern == AttackPattern.Circle)
            {
                GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 100.0f, CirclePhase.ToString(), stateColor, Color.Black);
            }

            if (LatchOntoAI != null && (State == AIState.Idle || LatchOntoAI.IsAttachedToSub))
            {
                foreach (Joint attachJoint in LatchOntoAI.AttachJoints)
                {
                    GUI.DrawLine(spriteBatch,
                        ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorA.X, -attachJoint.WorldAnchorA.Y)),
                        ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), GUIStyle.Green, 0, 4);
                }

                if (LatchOntoAI.AttachPos.HasValue)
                {
                    GUI.DrawLine(spriteBatch, pos,
                        ConvertUnits.ToDisplayUnits(new Vector2(LatchOntoAI.AttachPos.Value.X, -LatchOntoAI.AttachPos.Value.Y)), GUIStyle.Green, 0, 3);
                }
            }

            if (steeringManager is IndoorsSteeringManager pathSteering)
            {
                var path = pathSteering.CurrentPath;
                if (path != null)
                {
                    if (path.CurrentNode != null)
                    {
                        GUI.DrawLine(spriteBatch, pos,
                            new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
                            Color.DarkViolet, 0, 3);

                        GUI.DrawString(spriteBatch, pos - new Vector2(0, 100), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
                    }
                    for (int i = 1; i < path.Nodes.Count; i++)
                    {
                        var previousNode = path.Nodes[i - 1];
                        var currentNode = path.Nodes[i];
                        GUI.DrawLine(spriteBatch,
                            new Vector2(currentNode.DrawPosition.X, -currentNode.DrawPosition.Y),
                            new Vector2(previousNode.DrawPosition.X, -previousNode.DrawPosition.Y),
                            GUIStyle.Red * 0.5f, 0, 3);

                        GUIStyle.SmallFont.DrawString(spriteBatch,
                            currentNode.ID.ToString(),
                            new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
                            GUIStyle.Red);
                    }
                }
            }
            else
            {
                if (steeringManager.AvoidDir.LengthSquared() > 0.0001f)
                {
                    Vector2 hitPos = ConvertUnits.ToDisplayUnits(steeringManager.AvoidRayCastHitPosition);
                    hitPos.Y = -hitPos.Y;

                    GUI.DrawLine(spriteBatch, hitPos, hitPos + new Vector2(steeringManager.AvoidDir.X, -steeringManager.AvoidDir.Y) * 100, GUIStyle.Red, width: 5);
                    //GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(steeringManager.AvoidLookAheadPos.X, -steeringManager.AvoidLookAheadPos.Y), Color.Orange, width: 4);
                }
            }
            GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 4);
            GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
        }
    }
}
