using FMOD.Studio;
using FMODUnity;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;

public class SubtitleManager : MonoBehaviour
{
    [Header("Text")]
    public TMP_Text m_Text;
    [Header("Audio")]
    [SerializeField]
    private EventReference m_NarrationSFX;
    [SerializeField]
    private EventInstance m_NarrationSFXInst;
    [SerializeField]
    private EventReference m_TextScrollSFX;
    [SerializeField]
    private EventInstance m_TextScrollSFXInst;

    private float m_TimeElapsed;

    private bool m_FirstRun;

    private void OnEnable()
    {
        NarrationManager.m_UpdateSubtitile += UpdateText;
    }

    private void OnDisable()
    {
        NarrationManager.m_UpdateSubtitile -= UpdateText;
    }

    private void Start()
    {
        m_TimeElapsed = 0;
        m_Text.text = "";
        m_FirstRun = true;
    }

    private void UpdateText(string sentence, float waitTime)
    {
        FMOD.Studio.PLAYBACK_STATE state;

        m_NarrationSFXInst = AudioManager.instance.PlaySound(m_NarrationSFX);

        m_NarrationSFXInst.getPlaybackState(out state);

        if (m_FirstRun)
        {
            m_FirstRun = false;
            m_NarrationSFXInst.start();
        }
        else
        {
            m_NarrationSFXInst.getPlaybackState(out state);
            if (state == PLAYBACK_STATE.STOPPED)
            {
                m_NarrationSFXInst.start();
            }
        }
        StartCoroutine(TextScroll(sentence, waitTime));
    }

    // Wait time, how long the text will stay on the screen for + if the audio stops late, apply an offset
    private IEnumerator ClearText(float waitTime, bool earlyStop)
    {
        var offset = (waitTime - m_TimeElapsed) * Random.Range(0.6f, 0.95f);

        if (offset > 12.5)
        {
            offset = 10f;
        }

        if(offset < 5)
        {
            offset = Random.Range(5f, 7f);
        }

        float earlyOffset = 0;

        if (earlyStop)
        {
            earlyOffset = offset / Random.Range(2, 4);
            offset -= earlyOffset;
            yield return new WaitForSecondsRealtime(earlyOffset);
            AudioManager.instance.StopSound(m_NarrationSFXInst);
        }
        yield return new WaitForSecondsRealtime(offset);
        m_Text.text = "";
        m_TimeElapsed = 0;
    }

    private IEnumerator TextScroll(string sentence, float waitTime)
    {
        var characterLength = sentence.ToCharArray().Length;
        int randomStoppingValue = (int)Random.Range(characterLength * 0.6f, characterLength);
        var index = 0;
        bool earlyStop = false;

        // if (Random.Range(0f, 10f) > 6) earlyStop = true;
        yield return new WaitForSecondsRealtime(0);

        //m_Text.text = sentence;

        m_TextScrollSFXInst = AudioManager.instance.PlaySound(m_TextScrollSFX);
        m_TextScrollSFXInst.start();
        foreach (char c in sentence.ToCharArray())
        {
           index++;
           m_Text.text += c;
           float randomInterval = Random.Range(0.02f, 0.06f);
           yield return new WaitForSecondsRealtime(randomInterval);
           m_TimeElapsed += randomInterval;

           // Stop audio early based on probability
           if (randomStoppingValue == index && earlyStop)
           {
               AudioManager.instance.StopSound(m_NarrationSFXInst);
           }
        }
        m_TextScrollSFXInst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
        StartCoroutine(ClearText(waitTime, false));
    }
}