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

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    public GameObject GameOverUI;
    public GameObject VictoryUI;

    [Header("Orb Settings")]
    public int totalOrbs = 20;
    private int collectedOrbs = 0;

    [Header("UI")]
    public TMP_Text orbsCounter;
    public TMP_Text timertext;

    [Header("Nightfall Timer")]
    public float timeRemaining = 60f;
    private bool gameOver = false;

    public EnergyOrb[] allOrbs;


    [Header("References")]
    public PlayerController player;
    public TimeChanger timeManager;

    [Header("Procedural")]
    public int worldSeed;


    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        } else
        {
            Destroy(gameObject);
        }
    }


    void Start()
    {
        allOrbs = FindObjectsOfType<EnergyOrb>();
        UpdateOrbUI();
        UpdateTimerUI();
    }

    void Update()
    {
        if (gameOver) return;

        timeRemaining -= Time.deltaTime;

        if (timeRemaining <= 0f)
        {
            timeRemaining = 0f;
            GameOver();
        }
        UpdateTimerUI();

        if (Input.GetKeyDown(KeyCode.F5))
        {
            SaveSystem.Save(CreateSaveData());
        }

        if (Input.GetKeyDown(KeyCode.F9))
        {
            LoadGame(SaveSystem.Load());
        }

    }

    public void CollectOrb()
    {
        if (gameOver) return;

        collectedOrbs++;
        UpdateOrbUI();

        if (collectedOrbs >= totalOrbs)
        {
            Victory();
        }
    }

    void UpdateOrbUI()
    {
        if (orbsCounter != null)
        {
            orbsCounter.text = $"{collectedOrbs} / {totalOrbs}";
        }
    }

    void UpdateTimerUI()
    {
        if (timertext != null)
        {
            timertext.text = Mathf.Ceil(timeRemaining).ToString(); ;
        }
    }

    void Victory()
    {
        VictoryUI.SetActive(true);
        gameOver = true;

        Time.timeScale = 0f;

        Cursor.lockState = CursorLockMode.None;
        Cursor.visible = true;

        Debug.Log("YOU WIN!");
    }


    void GameOver()
    {
        GameOverUI.SetActive(true);
        gameOver = true;

        Time.timeScale = 0f;

        Cursor.lockState = CursorLockMode.None;
        Cursor.visible = true;

        Debug.Log("YOU LOSE!");
    }

    public void StartNewGame()
    {
        gameOver = false;

        // Reseting the timer
        timeRemaining = 60f;
        UpdateTimerUI();

        // Reseting all of the orbs
        foreach (var orb in allOrbs)
        {
            orb.Collected = false;
            orb.gameObject.SetActive(true);
        }
        collectedOrbs = 0;
        UpdateOrbUI();

        // Reset the player position and rotation
        if (player != null)
        {
            player.transform.position = Vector3.zero;
            player.transform.rotation = Quaternion.identity;

            // Reset stamina
            player.Stamina = player.maxStamina;
        }
    }

    /* Saving works
     * Loading works too, both ingame. sometimes.
     */

    public void RestartGame()
    {
        Time.timeScale = 1f;
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    public SaveData CreateSaveData()
    {
        SaveData data = new SaveData();

        data.playerPosition = player.transform.position;
        data.playerRotation = player.transform.rotation;
        data.stamina = player.Stamina;

        data.orbsCollected = collectedOrbs;
        data.remainingTime = timeRemaining;

        data.orbs.Clear();
        foreach (var orb in allOrbs)
        {
            data.orbs.Add(new OrbData
            {
                id = orb.ID,
                collected = orb.Collected
            });
        }

        return data;
    }





    public void LoadGame(SaveData data)
    {
        if (data == null) return;
        StartCoroutine(LoadPlayerNextFrame(data));
    }

    private IEnumerator LoadPlayerNextFrame(SaveData data)
    {
        yield return new WaitForEndOfFrame(); // wait for the scene too finish

        // Restore the player position and rotation
        player.transform.position = data.playerPosition;
        player.transform.rotation = data.playerRotation;

        // Restore the stamina
        player.Stamina = data.stamina;

        // Restore the timer
        timeRemaining = data.remainingTime;
        UpdateTimerUI();

        // Restore all of the orbs
        for (int i = 0; i < allOrbs.Length; i++)
        {
            allOrbs[i].Collected = data.orbs[i].collected;
            allOrbs[i].gameObject.SetActive(!data.orbs[i].collected);
        }

        collectedOrbs = data.orbsCollected;
        UpdateOrbUI();
    }









}
