using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public enum GameState
    {
        InMainMenu,
        Paused,
        Playing,
        GameOver,
        Won
    }

    public static GameManager gameManagerInstance { get; private set; }

    [SerializeField] int currentOrbCounter;
    [SerializeField] int maximumOrbs;

    [SerializeField] TextMeshProUGUI orbCounterText;

    private float initialTime;
    [SerializeField] float timeUntilNightfall;
    [SerializeField] TextMeshProUGUI timerText;

    [SerializeField] Transform playerTransform;

    public GameState gameState = GameState.InMainMenu;

    private void Awake()
    {
        if(gameManagerInstance == null)
        {
            gameManagerInstance = this;
            
            initialTime = timeUntilNightfall;

            SceneManager.sceneLoaded += OnSceneLoaded;

            DontDestroyOnLoad(gameObject);

        }
        else
        {
            Destroy(gameObject);
        }
    }

    private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if(scene.name == "MainMap")
        {
            currentOrbCounter = 0;
            timeUntilNightfall = initialTime;

            playerTransform = GameObject.Find("Player").transform;
            GameObject orbObject = GameObject.Find("Orb_Text");
            if (orbObject)
            {
                orbCounterText = orbObject.GetComponent<TextMeshProUGUI>();
            }

            GameObject timerObject = GameObject.Find("Timer");
            if (timerObject)
            {
                timerText = timerObject.GetComponent<TextMeshProUGUI>();
            }

            StartCoroutine(WaitAndSpawnOrbs());

            UpdateOrbUI();
            UpdateTimerUI();
        }
        else if(scene.name == "MainMenu")
        {
            currentOrbCounter = 0;
            timeUntilNightfall = initialTime;
        }
        else if(scene.name == "VictoryScene")
        {
            currentOrbCounter = 0;
            timeUntilNightfall = initialTime;
        }
        else if(scene.name == "GameOverScene")
        {
            currentOrbCounter = 0;
            timeUntilNightfall = initialTime;
        }
    }

    IEnumerator WaitAndSpawnOrbs()
    {
        yield return null;

        yield return new WaitForFixedUpdate();

        GenerateOrbs generator = GetComponent<GenerateOrbs>();
        if (generator) generator.StartGenerating(playerTransform);
    }

    private void Update()
    {
        if (gameState == GameState.Playing)
        {
            HandleTimer();
        }
    }

    private void HandleTimer()
    {
        if(timeUntilNightfall > 0)
        {
            timeUntilNightfall -= Time.deltaTime;
            UpdateTimerUI();
        }
        else
        {
            timeUntilNightfall = 0;
            GameOver();
        }
    }

    private void UpdateTimerUI()
    {
        if (timerText)
        {
            int minutes = Mathf.FloorToInt(timeUntilNightfall / 60);
            int seconds = Mathf.FloorToInt(timeUntilNightfall % 60);
            timerText.text = string.Format("{0:00}:{1:00}", minutes, seconds);
        }
    }

    public void IncreaseOrbCounter()
    {
        currentOrbCounter++;
        UpdateOrbUI();
        CheckAllOrbsCollected();
    }

    private void UpdateOrbUI()
    {
        if(orbCounterText != null)
        {
            orbCounterText.text = currentOrbCounter + "/" + maximumOrbs;
        }
    }

    private void CheckAllOrbsCollected()
    {
        if(currentOrbCounter >= maximumOrbs)
        {
            gameState = GameState.Won;
            SceneManager.LoadScene("VictoryScene");
        }
    }

    private void GameOver()
    {
        gameState = GameState.GameOver;
        SceneManager.LoadScene("GameOverScene");
    }

    public void StartGame()
    {
        gameState = GameState.Playing;
        SceneManager.LoadScene("MainMap");
    }

    public void GoBackToMainMenu()
    {
        gameState = GameState.InMainMenu;
        SceneManager.LoadScene("MainMenu");
    }

    public int GetMaximumOrbs()
    {
        return maximumOrbs;
    }
}
