using UnityEngine;
using ScrambleKit.Extensions;

namespace ScrambleKit.Weapons
{
    [RequireComponent(typeof(WeaponCore))]
    public class Melee : MonoBehaviour
    {
        public Sprite IdleArt;
        public Sprite WindupArt;
        public Sprite SwingArt;
        public Sprite RecoveryArt;

        public float WindupTime;
        public float SwingTime;
        public float RecoveryTime;

        public bool RotateToAimOnWindupAndSwing;

        private WeaponCore core;
        private SpriteRenderer rend;
        private Collider2D hitBox;
        private float lastTriggeredTime;

        void Attack()
        {
            if (core.IsReady && IsIdle())
                StartSwing();
        }

        private void StartSwing()
        {
            lastTriggeredTime = Time.fixedTime;
        }

        void FixedUpdate()
        {
            SetRotation();
            SetAnimation();
            SetHitBox();
        }

        private void SetRotation()
        {
            if (RotateToAimOnWindupAndSwing && (IsWindingUp() || IsSwinging()))
                FaceTowardAim();
            else
                transform.localEulerAngles = Vector3.zero;
        }

        private void SetAnimation()
        {
            if (IsWindingUp())
                rend.sprite = WindupArt;
            else if (IsSwinging())
                rend.sprite = SwingArt;
            else if (IsRecovering())
                rend.sprite = RecoveryArt;
            else
                rend.sprite = IdleArt;
        }

        private void SetHitBox()
        {
            hitBox.enabled = IsSwinging();
        }

        private bool IsIdle()
        {
            float sinceTrigger = Time.fixedTime - lastTriggeredTime;
            return sinceTrigger > WindupTime + SwingTime + RecoveryTime;
        }

        private bool IsRecovering()
        {
            float sinceTrigger = Time.fixedTime - lastTriggeredTime;
            return sinceTrigger > WindupTime + SwingTime &&
                   sinceTrigger <= WindupTime + SwingTime + RecoveryTime;
        }

        private bool IsSwinging()
        {
            float sinceTrigger = Time.fixedTime - lastTriggeredTime;
            return sinceTrigger > WindupTime &&
                   sinceTrigger <= WindupTime + SwingTime;
        }

        private bool IsWindingUp()
        {
            float sinceTrigger = Time.fixedTime - lastTriggeredTime;
            return sinceTrigger <= WindupTime;
        }

        private void FaceTowardAim()
        {
            float swingAngle = ((Vector2)transform.position).AngleTo(core.Input.AimingAt);
            transform.localEulerAngles = new Vector3(0, 0, swingAngle);
        }

        void Start()
        {
            core = GetComponent<WeaponCore>();
            rend = GetComponent<SpriteRenderer>();
            hitBox = GetComponent<Collider2D>();
        }
    }
}
