using UnityEngine;
using Saltosion.OneWeapon.Enemies;
using Saltosion.OneWeapon.Effects;

namespace Saltosion.OneWeapon.AI.Behaviours {
    enum StompState {
        ReadyToStomp,
        PreparingStomp,
        RecoveringFromStomp,
        CoolingDown,
    }

    [RequireComponent(typeof(Follow))]
    public class Stomp : AIBehaviour {
        public float StompCooldown;
        [Tooltip("How long the stomp animation is")]
        public float StompDuration;
        [Tooltip("If StompDuration is 1.0 and this is 0.75, the stomp explosion will happen after the first 3/4ths of the stomp animation.")]
        public float StompExplosionTime;
        public float StompRadius;
        public float LoweredStompCooldown;
        public float LoweredStompCooldownRadius;

        public bool Stomping { get { return State == StompState.PreparingStomp || State == StompState.RecoveringFromStomp; } }
        public bool CoolingDown { get { return State == StompState.CoolingDown; } }

        private float CurrentCooldown;
        private StompState State = StompState.ReadyToStomp;

        private Follow FollowBehaviour;

        private void Start() {
            FollowBehaviour = GetComponent<Follow>();
        }

        private void Update() {
            if (CurrentCooldown > 0) {
                CurrentCooldown -= Time.deltaTime;
            } else {
                // This is reached every time the cooldown reaches zero, for one frame
                // (except when ReadyToStomp, when this is called every loop until the next stomp,
                //   since then the cooldown isn't reset to something >0)
                switch (State) {
                    case StompState.PreparingStomp:
                        // TODO(jens): Consider adding squish and stretch animation for this
                        CurrentStatus = "STOMP";
                        DoStomp();
                        CurrentCooldown = StompDuration - StompExplosionTime;
                        State = StompState.RecoveringFromStomp;
                        break;
                    case StompState.RecoveringFromStomp:
                        CurrentStatus = "CoolingDown";
                        CurrentCooldown = GetDistance() < LoweredStompCooldownRadius ? LoweredStompCooldown : StompCooldown;
                        State = StompState.CoolingDown;
                        break;
                    case StompState.CoolingDown:
                        CurrentStatus = "CooledDown";
                        State = StompState.ReadyToStomp;
                        break;
                    case StompState.ReadyToStomp:
                        CurrentStatus = "ReadyToStomp";
                        break;
                }
            }

        }

        public override bool CanBehave() {
            return State != StompState.CoolingDown;
        }

        public override void Execute() {
            if (State == StompState.ReadyToStomp) {
                CurrentCooldown = StompExplosionTime;
                State = StompState.PreparingStomp;
                CurrentStatus = "Stomping";
            }
        }

        private float GetDistance() {
            return FollowBehaviour.Target == null ? float.PositiveInfinity : (FollowBehaviour.Target.position - transform.position).magnitude;
        }

        private void DoStomp() {
            Debug.Log("STOMP");
            Camera.main.GetComponent<CameraFX>().ScreenShake(7f);
        }

        private void OnDrawGizmosSelected() {
            Gizmos.color = new Color(1f, 0f, 0f, 0.3f);
            Gizmos.DrawWireSphere(transform.position, LoweredStompCooldownRadius);
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position, StompRadius);
        }
    }
}
