using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;

public class JetPack : MonoBehaviour
{
    [System.Serializable]
    public class Settings
    {
        public float Force = 5;
        public float Duration = 10;
    }

    [System.Serializable]
    public class References
    {
        public BoxCollider Collider;
        public SphereCollider Trigger;
        public Rigidbody Rigidbody;
        public Transform Load;
        public ParticleSystem[] Particles;
        public InputActionAsset InputActions;
    }

    [System.Serializable]
    public class StateContainer
    {
        public bool Equiped;
    }

    [SerializeField]
    public Settings _settings;

    [SerializeField]
    public References _references;

    [SerializeField]
    public StateContainer _state;

    private bool _wasPressed;
    private float _duration = 0;
    private float _smooth = 0;

    private InputAction _jumpAction;

    void OnTriggerEnter(Collider col)
    {
        if (Player.Instance && Player.Instance.gameObject == col.gameObject)
        {
            Equip();
        }
    }

    void Awake()
    {
        _duration = _settings.Duration;
        _jumpAction = _references.InputActions.FindActionMap("Player").FindAction("Jump");
    }

    void Update()
    {
        if (_state.Equiped && Player.Instance)
        {
            if (_duration > 0)
            {
                if (_jumpAction.IsPressed())
                {
                    _duration -= Time.deltaTime;
                    _smooth = Mathf.Clamp01(_smooth + Time.deltaTime);
                }
                else
                {
                    _smooth = Mathf.Clamp01(_smooth - 2 * Time.deltaTime);
                }

                Player.Instance.SetForce(Vector3.up * _settings.Force * _smooth);

                _references.Load.localScale = new Vector3(1, _duration / _settings.Duration, 1);

                foreach (ParticleSystem pSystem in _references.Particles)
                {
                    if (!pSystem.isPlaying && _smooth >= .1f)
                        pSystem.Play();
                    if (pSystem.isPlaying && _smooth <= .05f)
                        pSystem.Stop();
                }
            }
            else
            {
                Unequip();
            }
        }
    }

    private void Equip()
    {
        if (_state.Equiped || _duration <= 0 ||!Player.Instance)
            return;

        _wasPressed = false;
        _state.Equiped = true;
        _duration = _settings.Duration;

        _references.Collider.enabled = false;
        _references.Trigger.enabled = false;
        _references.Rigidbody.isKinematic = true;

        transform.parent = Player.Instance.transform.GetChild(0).GetChild(1).GetChild(0);
        transform.localPosition = new Vector3(0, .3f, -.4f);
        transform.localEulerAngles = Vector3.zero;
    }

    private void Unequip()
    {
        if (!_state.Equiped)
            return;

        Player.Instance.SetForce(Vector3.zero);

        _state.Equiped = false;
        _duration = _settings.Duration;

        transform.parent = null;

        Vector3 random = new Vector3(UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1), UnityEngine.Random.Range(-1, 1)).normalized;

        _references.Collider.enabled = true;
        _references.Trigger.enabled = false;
        _references.Rigidbody.isKinematic = false;
        _references.Rigidbody.AddRelativeTorque(random, ForceMode.Impulse);

        _references.Load.gameObject.SetActive(false);

        foreach (ParticleSystem pSystem in _references.Particles)
            if (pSystem.isPlaying)
                pSystem.Stop();
    }
}
