using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

#if UNITY_EDITOR
using UnityEditor;
#endif

// updates visible subtitle text and a character portrait of the speaker
public class DialogueUI : MonoBehaviour
{
    [SerializeField] private DialogueSystem _dialogue;

    [SerializeField] private float _fadeTime;
    [SerializeField] private CanvasGroup _dialogueGroup;
    [SerializeField] private TMP_Text _text;
    [SerializeField] private GameObject _portrait;

    private bool _dismissed;

    private void OnEnable()
    {
        _dialogue.onDialogueLine += (_, dl) => ShowLine(dl);

        _text.text = string.Empty;
        _portrait.SetActive(false);
    }

    public void Dismiss()
    {
        _dismissed = true;
    }

    private IEnumerator _subtitleRoutine;
    
    private void ShowLine(DialogueLine line)
    {
        // there is a line currently being shown, abort its coroutine and hide ui elements
        if (_subtitleRoutine != null && _text.text != null)
        {
            HideSubtitle();
            StopCoroutine(_subtitleRoutine);
        }

        _subtitleRoutine = ShowLineCR(line.text, line.duration);
        StartCoroutine(_subtitleRoutine);   
    }

    private IEnumerator ShowLineCR(string text, float duration)
    {
        // update text and show portrait
        float a = 0f;
        _dialogueGroup.alpha = a;
        _text.text = text;
        _portrait.SetActive( true );

        while ( a < 1f )
        {
            yield return null;
            a += Time.deltaTime / _fadeTime;
            _dialogueGroup.alpha = a;
        }

        _dialogueGroup.alpha = 1f;

        // wait until timeout of dismissal
        var timer = 0f;
        while (!_dismissed && timer < duration)
        {
            timer += Time.deltaTime;

            // wait for next frame
            yield return null;
        }
        
        while ( a > 0f )
        {
            yield return null;
            a -= Time.deltaTime / _fadeTime;
            _dialogueGroup.alpha = a;
        }

        _dialogueGroup.alpha = 0f;
        
        // hide ui elements
        HideSubtitle();
        
        _dismissed = false;
    }

    private void HideSubtitle()
    {
        _text.text = string.Empty;
        _portrait.SetActive( false );
    }
}

#region Editor
#if UNITY_EDITOR

[CustomEditor(typeof(DialogueUI))]
public class DialogueUIEditor : Editor
{
    private DialogueUI _dialogueUI;

    private void OnEnable()
    {
        _dialogueUI = target as DialogueUI;
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        if (!Application.isPlaying) return;
        
        if (GUILayout.Button("Dismiss"))
        {
            _dialogueUI.Dismiss();
        }
    }
}

#endif
#endregion