using Ktyl.Util;
using System.Collections;
using FMOD.Studio;
using FMODUnity;
using PathCreation;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UIElements;
using STOP_MODE = FMOD.Studio.STOP_MODE;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class RollingBoulder : MonoBehaviour
{
    // how long it takes to travel the length of the path
    [SerializeField] private float speed;
    [FormerlySerializedAs("boulder")] [SerializeField] private Transform boulderMove;
    [SerializeField] private Transform boulderSpin;
    [SerializeField] private SerialFloat objectTimeScale;
    [SerializeField] private PathCreator path;
    [SerializeField] private Killbox _killbox;
    [SerializeField] private string _fmodKey;
    [SerializeField] private float _resetTime;
    [SerializeField] private float _rotationSpeed;
    
    private bool _triggered = false;
    private bool _stopped;
    private EventInstance _fmodEvent;

    void Start()
    {
        _fmodEvent = RuntimeManager.CreateInstance( _fmodKey );
        RuntimeManager.AttachInstanceToGameObject( _fmodEvent, boulderMove.transform, (Rigidbody)null );
    }

    private void Update()
    {
        _killbox.gameObject.SetActive(!_stopped && objectTimeScale > 0.5f);

        if (!_stopped)
        {
            var dt = Time.deltaTime * objectTimeScale;
            boulderSpin.transform.Rotate(new Vector3(0,0,_rotationSpeed) * dt);
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        // Checks to make sure other collider is the Player using tag.
        if (other.gameObject.CompareTag("Player"))
        {
            Trigger();
        }
    }

    public void Trigger()
    {
        if (_triggered) return;
        
        _fmodEvent.start();
        
        StartCoroutine(RollingStone());
    }
    
    private IEnumerator RollingStone()
    {
        _triggered = true;
        
        var d = 0f;
        var pathLength = path.path.length;

        while (_triggered && d < pathLength)
        {
            d += Time.deltaTime * objectTimeScale * speed;

            var pos = path.path.GetPointAtDistance(d);

            boulderMove.transform.position = pos;

            yield return null;
        }

        if (_triggered)
        {
            _stopped = true;
            boulderMove.position = path.path.GetPointAtTime(0.999f);
        }

        var resetElapsed = 0f;

        while (resetElapsed < _resetTime)
        {
            resetElapsed += Time.deltaTime * objectTimeScale;
            yield return null;
        }
        
        Reset();
    }

    public void Reset()
    {
        boulderMove.transform.position = path.path.GetPointAtTime(0);
        _triggered = false;
        _killbox.enabled = true;
        _stopped = false;
        _fmodEvent.stop( STOP_MODE.IMMEDIATE );
    }
}

#if UNITY_EDITOR
[CustomEditor(typeof(RollingBoulder))]
public class RollingBoulderEditor : Editor
{
    private RollingBoulder _data;

    private void OnEnable()
    {
        _data = target as RollingBoulder;
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        
        if (!Application.isPlaying) return;
        
        if (GUILayout.Button("Trigger"))
        {
            _data.Trigger();
        }

        if (GUILayout.Button("Reset"))
        {
            _data.Reset();
        }
    }
}

#endif
