using System;
using System.Collections;
using Ktyl.Util;
using System.Collections.Generic;
using FMODUnity;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Serialization;
using UnityEngine.UI;

public class PickUpDisplay : MonoBehaviour
{
    [System.Serializable]
    struct FadeElement
    {
        public float Delay;
        public float Duration;
        public CanvasGroup Renderer;

        public float GetAlpha( float t )
            => Mathf.Clamp01( ( t - Delay )  / Duration );

        public float GetAlphaInverse( float t )
            => 1f - GetAlpha( t );
    }

    [FormerlySerializedAs( "_elements" )] [SerializeField]
    private FadeElement[] _fadeInElements;
    
    [SerializeField]
    private FadeElement[] _fadeOutElements;

    [SerializeField]
    private float _dialogueDelay;
    
    [SerializeField]
    [EventRef]
    private string _unlockedSfx;
    
    [SerializeField]
    private float _unlockedSfxDelay;
    
    [SerializeField] private GameObject artefactUI;
    [FormerlySerializedAs( "artefactText" )] 
    [SerializeField] private TMP_Text artefactTitle;
    [SerializeField] private TMP_Text artefactDescription;
    [SerializeField] private DialogueSystem dialogue;
    [SerializeField] private ArtefactSystem artefacts;
    [SerializeField] private ArtefactPreview _preview;

    [SerializeField]
    private Button _continueButton;

    [SerializeField]
    private GameEvent _uiOpen;
    
    [SerializeField]
    private GameEvent _uiClose;

    private Artefact _chosenArtefact;

    private Coroutine _currentFade;

    private void Start()
    {
        EventHandler.current.onArtefactUI += PopUpOn;
        _continueButton.enabled = false;
    }

    private IEnumerator AnimateIn()
    {
        _uiOpen.Raise();
        artefactTitle.text = _chosenArtefact.Name;
        artefactDescription.text = DialogueDatabase.ReadDialogue( _chosenArtefact.descriptionKey );
        // inputSettings.updateMode = (InputSettings.UpdateMode)1;
        _preview.Preview( _chosenArtefact.Prefab );
        
        bool isComplete = false;
        bool hasSpoken = false;
        bool hasClinged = false;

        foreach ( var fader in _fadeInElements )
        {
            fader.Renderer.alpha = 0f;
        }
        
        artefactUI.SetActive(true);

        yield return null;
            
        float t = 0;
        while ( true )
        {
            t += Time.deltaTime;
            
            isComplete = true;
            
            foreach ( var fader in _fadeInElements )
            {
                float alpha = fader.GetAlpha( t );
                float oneMinusAlpha = 1f - alpha;

                fader.Renderer.alpha = 1f - oneMinusAlpha * oneMinusAlpha;

                if ( alpha < 1f )
                {
                    isComplete = false;
                }
            }

            if ( t < _dialogueDelay )
            {
                isComplete = false;
            }
            else if (!hasSpoken)
            {
                hasSpoken = true;
                dialogue.PlayLine( _chosenArtefact.dialogueKey );
            }

            if ( t < _unlockedSfxDelay )
            {
                isComplete = false;
            }
            else if ( !hasClinged )
            {
                hasClinged = true;
                RuntimeManager.PlayOneShot( _unlockedSfx );
            }

            if ( isComplete )
                break;

            yield return null;
        }

        _continueButton.enabled = true;
        _continueButton.Select();
    }

    private IEnumerator AnimateOut()
    {
        yield return null;
        bool isComplete = false;
        
        _continueButton.enabled = false;

        foreach ( var fader in _fadeInElements )
        {
            fader.Renderer.alpha = 1f;
        }

        yield return null;
        
        _preview.Dismiss();
        _uiClose.Raise();
            
        float t = 0;
        while ( true )
        {
            t += Time.deltaTime;
            
            isComplete = true;
            
            foreach ( var fader in _fadeInElements )
            {
                float alpha = fader.GetAlphaInverse( t );
                float oneMinusAlpha = 1f - alpha;

                fader.Renderer.alpha = 1f - oneMinusAlpha * oneMinusAlpha;

                if ( alpha > 0f )
                {
                    isComplete = false;
                }
            }

            yield return null;
            
            if ( isComplete )
                break;
        }
        
        artefactUI.SetActive( false );
        _chosenArtefact = null;
        
        yield return null;
    }

    private void Update()
    {
        var artefact = artefacts.GetNearbyArtefact();
        if (!artefact) return;
        
        _chosenArtefact = artefact;
    }

    public void PopUpOn()
    {
        if (_currentFade != null)
            StopCoroutine( _currentFade );
        
        _currentFade = StartCoroutine( AnimateIn() );
    }

    public void PopUpOff()
    {
        if (_currentFade != null)
            StopCoroutine( _currentFade );
        
        _currentFade = StartCoroutine( AnimateOut() );
        // inputSettings.updateMode = (InputSettings.UpdateMode)2;
    }
}