using UnityEngine;
using Saltosion.OneWeapon.Player;
using Saltosion.OneWeapon.Enemies;

namespace Saltosion.OneWeapon.AI.Behaviours {
    [RequireComponent(typeof(Follow), typeof(Enemy))]
    public class MeleeAttackFollowed : AIBehaviour {
        [Tooltip("This should be at 0,0,0 locally by default.")]
        public Transform AnimatableTransform;
        public float MeleeRange;
        public float AttackAnimationLength;
        public float ReleaseAnimationLength;
        public float CooldownLength;

        [HideInInspector]
        public bool Attacking;

        private Enemy Enemy;
        private Follow Follow;
        private bool AttackHit;
        private float AnimationProgress;
        private float CooldownProgress;
        private Vector3 LocalOrigin;

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

            if (AnimatableTransform.localPosition.magnitude != 0) {
                Debug.LogWarning($"{name} has an animated melee attack, and AnimatableTransform is not at local origin!");
            }
            LocalOrigin = AnimatableTransform.localPosition;
            Reset();
        }

        private void Reset() {
            AttackHit = false;
            AnimationProgress = 0.0f;
            CooldownProgress = 1.0f;
            AnimatableTransform.localPosition = LocalOrigin;
        }

        private void Update() {
            if (CooldownProgress > 0) {
                CurrentStatus = "Cooldown";
                CooldownProgress -= Time.deltaTime / CooldownLength;
            }
            Attacking = CooldownProgress < 0.4f && Follow.Target != null &&
                (Follow.Target.position - Enemy.transform.position).magnitude <= MeleeRange * 2f;
        }

        public override bool CanBehave() {
            bool CanBehave = Follow.Target != null && (Follow.Target.position - Enemy.transform.position).magnitude <= MeleeRange;
            return CanBehave;
        }

        public override void Execute() {
            if (CooldownProgress > 0) {
                return;
            } else {
                Attacking = true;
            }

            Vector2 Root = AnimatableTransform.parent.position + LocalOrigin;
            Vector2 Target = Follow.Target.transform.position;
            if (!AttackHit) {
                CurrentStatus = "Hit";
                AnimationProgress += Time.deltaTime / AttackAnimationLength;
                AnimatableTransform.position = Vector2.Lerp(Root, Target, AnimationProgress);
                if (AnimationProgress >= 1.0f) {
                    // Attack hit, deal damage and start return animation
                    TakeFunDamage();
                    AttackHit = true;
                    AnimationProgress = 0.0f;
                }
            } else {
                CurrentStatus = "Retreat";
                AnimationProgress += Time.deltaTime / ReleaseAnimationLength;
                AnimatableTransform.position = Vector2.Lerp(Target, Root, AnimationProgress);
                if (AnimationProgress >= 1.0f) {
                    // Attack finished, reset
                    Reset();
                }
            }
        }

        private void TakeFunDamage() {
            PlayerFun Player = Follow.Target.GetComponent<PlayerFun>();
            if (Player != null) {
                Player.TakeDamage();
            }
        }

        private void OnDrawGizmosSelected() {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position, MeleeRange);
        }
    }
}
