using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;

public class GameManager : MonoBehaviour
{
    private const float FadeDuration = 0.5f;
    public static GameManager Instance;

    public enum SceneState
    {
        Main,
        Map,
        Battle
    }

    public GameObject MainMenu;
    public OptionsManager Options;
    public MapManager Map;
    public BattleManager Battle;
    public CanvasGroup Darkener;
    public TypingText IntroText;
    public SceneState State => _state;
    
    private SceneState _state;
    private int _magnification;
    
    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        
    }

    void Update()
    {
        if (Input.GetKeyUp(KeyCode.Escape))
        {
            ShowOptions();
        }
#if UNITY_EDITOR
        if (Input.GetKeyUp(KeyCode.F))
        {
            DipToBlack(null);
        }
#endif
    }

    public IEnumerator FadeToBlack(UnityAction done)
    {
        float t = Time.time + FadeDuration;
        Darkener.alpha = 0;
        float alpha = 0;
        while (Time.time < t)
        {
            alpha = (t - Time.time) / FadeDuration;
            Darkener.alpha = 1 - alpha;
            yield return null;
        }

        Darkener.alpha = 1;
        yield return new WaitForSeconds(0.3f);
        done?.Invoke();
    }
    
    public IEnumerator FadeFromBlack(UnityAction done)
    {
        float t = Time.time + FadeDuration;
        Darkener.alpha = 0;
        float alpha = 1;
        while (Time.time < t)
        {
            alpha = (t - Time.time) / FadeDuration;
            Darkener.alpha = alpha;
            yield return null;
        }

        Darkener.alpha = 0;
        yield return new WaitForSeconds(0.3f);
        done?.Invoke();
    }

    private void DipToBlack(UnityAction done)
    {
        StartCoroutine(FadeToBlack(() =>
        {
            done?.Invoke();
            StartCoroutine(FadeFromBlack(null));
        }));
    }
    
    private void ShowOptions()
    {
        Options.gameObject.SetActive(!Options.gameObject.activeSelf);
    }

    public void StartGame()
    {
        DipToBlack(() =>
        {
            SwitchScene(SceneState.Map);
        });
    }

    public void RestartGame()
    {
        DipToBlack(() =>
        {
            SceneManager.LoadScene("Scenes/MainMenu");
        });
    }

    public void Quit()
    {
        DipToBlack(() =>
        {
            Application.Quit();
        });
    }

    public bool BlockInput()
    {
        return Options.gameObject.activeSelf;
    }

    public void DoBattle(Enemy enemy, MapLocation.TerrainType terrain)
    {
        AudioManager.Instance.PlayFightMusic();
        SwitchScene(SceneState.Battle);
        Battle.CurrentTerrain = terrain;
        Battle.InitBattle(enemy);
    }

    public void ReturnToMap()
    {
        AudioManager.Instance.PlayMenuMusic();
        SwitchScene(SceneState.Map);
    }

    private void SwitchScene(SceneState s)
    {
        switch (s)
        {
            case SceneState.Main:
            {
                MainMenu.gameObject.SetActive(true);
                Map.gameObject.SetActive(false);
                Battle.gameObject.SetActive(false);
                break;
            }
            case SceneState.Map:
            {
                MainMenu.gameObject.SetActive(false);
                Map.gameObject.SetActive(true);
                Battle.gameObject.SetActive(false);
                break;
            }
            case SceneState.Battle:
            {
                MainMenu.gameObject.SetActive(false);
                Map.gameObject.SetActive(false);
                Battle.gameObject.SetActive(true);
                break;
            }
        }
    }
}
