using UnityEngine;
using Saltosion.OneWeapon.Enemies;

namespace Saltosion.OneWeapon.AI.Behaviours {
    [RequireComponent(typeof(Enemy))]
    public class Wander : AIBehaviour {
        public float MaxWalkingDistance;
        public float MinWalkingDistance;
        public float SubjectRadius;
        public float StopLength;

        private Enemy Enemy;
        private Vector2 Target;
        private float StopTime;
        private bool Stopped = true;

        private void Start() {
            Enemy = GetComponent<Enemy>();
            StopTime = Time.time;
        }

        public override bool CanBehave() {
            return true;
        }

        public override void Execute() {
            Vector2 SubjectPosition = (Vector2)Enemy.transform.position;
            if ((Target - SubjectPosition).magnitude > SubjectRadius) {
                Enemy.StartMovingTo(Target);
                CurrentStatus = "Move";
                Stopped = false;
                return;
            } else if (!Stopped) {
                Stopped = true;
                StopTime = Time.time;
                Target = SubjectPosition;
            } else if (Time.time - StopTime > StopLength) {
                // The AI is near the target, and has waited for StopTime.
                // Now we pick a new target.
                CurrentStatus = "Search";
                int i = 0;
                while ((Target - SubjectPosition).magnitude <= SubjectRadius) {
                    i++;
                    if (i > 100) {
                        Debug.LogWarning($"Wander behaviour took over 100 tries to find a wander position, '{Enemy.name}' is stuck!");
                        break;
                    }
                    float Distance = MinWalkingDistance + (MaxWalkingDistance - MinWalkingDistance) * Random.value;
                    float Direction = Random.value * Mathf.PI * 2f;
                    Vector2 Delta = new Vector2(Mathf.Cos(Direction), Mathf.Sin(Direction)) * Distance;
                    RaycastHit2D Hit = Physics2D.Raycast(SubjectPosition + Delta.normalized * SubjectRadius, Delta.normalized, Distance);
                    if (Hit.rigidbody == null) {
                        Target = SubjectPosition + Delta;
                    }
                }
            } else {
                CurrentStatus = "Stop";
            }

            Enemy.StopMoving();
        }
    }
}
