using Intrepid.Structures;
using Intrepid.Utilities;
using UnityEngine;

namespace Intrepid.Gameplay.Entities.Player.Sentinel.StateMachine.States
{
    public class SentinelStateKnockdown : SentinelState
    {
        [GroupConfigurations, SerializeField] private AnimationClip knockdown;
        [GroupConfigurations, SerializeField] private AnimationClip knockout;

        private Vector2 KnockdownForce { get; set; }
        private float KnockoutTime { get; set; }
        private Timer KnockdownTimer { get; } = new();
        private Timer KnockoutTimer { get; } = new();
        private Timer RecoverTimer { get; } = new();
        
        public override SentinelStateType GetStateKey()
        {
            return SentinelStateType.Knockdown;
        }

        protected override void Subscriptions()
        {
        }

        protected override void RunOnEnter(ParameterStore ps)
        {
            Brain.Entity.ModelAnimation.CrossFade(knockdown, 0.1f);
            KnockdownForce = ps.Get<Vector2>(SentinelConstants.Parameters.KnockdownForce);
            Brain.Entity.ChangeOrientation(-KnockdownForce.normalized);
            KnockoutTime = KnockdownForce.sqrMagnitude * Brain.Config.Knockdown.KnockoutTimeMultiplier;
            Brain.Entity.DesiredVelocity = Vector2.ClampMagnitude(KnockdownForce, Brain.Config.Knockdown.MaxKnockdownStrength);
            KnockdownTimer.Start();
            KnockoutTimer.Stop();
            RecoverTimer.Stop();
        }

        protected override void RunOnExit()
        {
        }

        public override void RunOnUpdate()
        {
            if (RecoverTimer.IsRunning)
            {
                RecoverTimer.Update(Timer.ScaledTime);
                if (RecoverTimer.Check(Brain.Config.Knockdown.RecoverDuration))
                {
                    RecoverTimer.Stop();
                    Brain.ChangeState(SentinelStateType.Idle);
                }
                
                return;
            }
            
            if (KnockoutTimer.IsRunning)
            {
                KnockoutTimer.Update(Timer.ScaledTime);
                if (KnockoutTimer.Check(Brain.Config.Knockdown.RecoverDuration))
                {
                    KnockoutTimer.Stop();
                    RecoverTimer.Start();
                }
                
                return;
            }

            if (KnockdownTimer.IsNotRunning)
            {
                if (Brain.Entity.ModelAnimation.IsPlaying(knockout))
                {
                    if (Brain.Entity.ModelAnimation.IsFinished)
                    {
                        KnockoutTimer.Start();
                        Brain.Entity.DesiredVelocity = Vector2.zero;
                    }
                }

                return;
            }
            
            KnockdownTimer.Update(Timer.ScaledTime);
            if (KnockdownTimer.Check(Brain.Config.Knockdown.KnockdownDuration))
            {
                KnockdownTimer.Stop();
                Brain.Entity.ModelAnimation.CrossFade(knockout, 0.1f);
            }
        }
    }
}