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

public class Tutorial : MonoBehaviour
{
    [SerializeField] private GameObject message;
    [SerializeField] private GameObject tutorialText;
    [SerializeField] private GameObject spaceBar;
    [SerializeField] private GameObject combo;
    [SerializeField] private GameObject inputKey;
    [SerializeField] private GameObject checkmark;
    [SerializeField] private PlayerCombat playerCombat;
    
    [Header("Key Assets")]
    [SerializeField] private Sprite[] keySprites;

    private TextMeshProUGUI _textComponent;
    private Image _comboImageComponent;
    private Image _keyImageComponent;

    private int _tutorialStage;
    private bool _isStageInProgress = false;
    
    private Coroutine _flickerCoroutine;

    void Awake()
    {
        _textComponent = tutorialText.GetComponent<TextMeshProUGUI>();
        _comboImageComponent = combo.GetComponent<Image>();
        _keyImageComponent = inputKey.GetComponent<Image>();
    }

    private void Start()
    {
        //set the game manager state to tutorial
        GameManager.Instance.CurrentState = GameState.Tutorial;
    }

    void Update()
    {
        if (_isStageInProgress) return;
        
        switch (_tutorialStage)
        {
            case 0:
                StartCoroutine(ShowNothing(1.0f));
                break;
            case 1:
                StartCoroutine(ShowMessage("Welcome to TUM! Try\nmoving around using WASD."));
                break;
            case 2:
            {
                StartCoroutine(ShowMessage("Press E to zoom in. Try \n these moves next."));
                break; 
            }
            case 3:
            {
                StartCoroutine(ShowButtonCombo(1.0f, "Punch", keySprites[0], CombatState.Punch));
                break;
            }
            case 4:
            {
                StartCoroutine(ShowButtonCombo(1.0f, "Block (press or press & hold)", keySprites[1], CombatState.Block));
                break;
            }
            case 5:
            {
                StartCoroutine(ShowButtonCombo(1.0f, "Kick", keySprites[2], CombatState.Kick));
                break;
            }
            case 6:
            {
                StartCoroutine(ShowButtonCombo(1.0f, "Slide (after walking)", keySprites[3], CombatState.Slide));
                break;
            }
            case 7:
            {
                StartCoroutine(ShowButtonCombo(1.0f, "Punch Combo", keySprites[4], playerCombat.punchMove2));
                break;
            }
            case 8:
            {
                StartCoroutine(ShowButtonCombo(1.0f, "Swing Combo", keySprites[5], playerCombat.swingMove));
                break;
            }
            case 9:
            {
                StartCoroutine(ShowMessage("Well done! Now go beat up\nstudents and defeat ProfessorX."));
                break; 
            }
            case 10:
                GameManager.Instance.GoToMainMenu();
                break;
        }
    }
    
    IEnumerator ToggleSpaceBarVisibility()
    {
        while (true)
        {
            spaceBar.SetActive(true);
            yield return new WaitForSeconds(0.5f);
            
            spaceBar.SetActive(false);
            yield return new WaitForSeconds(0.5f);
        }
    }

    private IEnumerator ShowNothing(float showDuration)
    {
        _isStageInProgress = true;
        message.SetActive(false);
        spaceBar.SetActive(false);
        combo.SetActive(false);
        inputKey.SetActive(false);
        checkmark.SetActive(false);
        yield return new WaitForSeconds(showDuration);
        _tutorialStage++;
        _isStageInProgress = false;
    }

    IEnumerator ShowMessage(string messageContent)
    {
        _isStageInProgress = true;
        message.SetActive(true);
        spaceBar.SetActive(true);
        combo.SetActive(false);
        inputKey.SetActive(false);
        checkmark.SetActive(false);
        _textComponent.text = messageContent;
    
        // do space bar flickering
        if (_flickerCoroutine != null) StopCoroutine(_flickerCoroutine);
        _flickerCoroutine = StartCoroutine(ToggleSpaceBarVisibility());
        
        while (!Input.GetKeyDown(KeyCode.Space))
        {
            yield return null;
        }
        
        // stop space bar flickering
        if (_flickerCoroutine != null) 
        {
            StopCoroutine(_flickerCoroutine);
            _flickerCoroutine = null;
        }
        _tutorialStage++;
        _isStageInProgress = false;
    }

    private IEnumerator ShowButtonCombo(float showDuration, string messageContent, Sprite keySprite, CombatState playerCombatState)
    {
        _isStageInProgress = true;
        message.SetActive(true);
        spaceBar.SetActive(false);
        combo.SetActive(false);
        inputKey.SetActive(true);
        checkmark.SetActive(false);
        _textComponent.text = messageContent;
        _keyImageComponent.sprite = keySprite;
        while (playerCombat.state != playerCombatState)
        {
            yield return null;
        }
        checkmark.SetActive(true);
        yield return new WaitForSeconds(showDuration);
        _tutorialStage++;
        _isStageInProgress = false;
    }
    
    private IEnumerator ShowButtonCombo(float showDuration, string messageContent, Sprite keySprite, CombatMove playerCombatMove)
    {
        _isStageInProgress = true;
        message.SetActive(true);
        spaceBar.SetActive(false);
        combo.SetActive(true);
        inputKey.SetActive(false);
        checkmark.SetActive(false);
        _textComponent.text = messageContent;
        _comboImageComponent.sprite = keySprite;
        while (playerCombat.inputBufferMove.Item1 != playerCombatMove)
        {
            yield return null;
        }
        checkmark.SetActive(true);
        yield return new WaitForSeconds(showDuration);
        _tutorialStage++;
        _isStageInProgress = false;
    }
    
}
