using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using ToolBox.Serialization;

public class SaveManager : MonoBehaviour
{
    public static SaveManager Instance;

    private string SAVE_KEY = "SaveData1";
    [HideInInspector] public GameObject player;
    [HideInInspector] public PlayerAmmoCounter playerAmmoCounter;
    [HideInInspector] public PlayerHealth playerHealth;
    public Save_Checkpoint[] currentCheckpoints;

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

    }
    private void OnEnable()
    {
        SceneManager.sceneLoaded += OnSceneLoaded;

    }
    private void OnDisable()
    {
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }

    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        player = GameObject.FindGameObjectWithTag("Player");
        playerAmmoCounter = player.GetComponentInChildren<PlayerAmmoCounter>();
        playerHealth = player.GetComponent<PlayerHealth>();

        Transform checkpoints = GameObject.Find("Checkpoints").transform;
        currentCheckpoints = new Save_Checkpoint[checkpoints.childCount];
        foreach (Transform checkpoint in checkpoints)
        {
            if (checkpoint.TryGetComponent(out Save_Checkpoint saveCheckpoint))
            {
                saveCheckpoint.saveManager = this;
                currentCheckpoints[saveCheckpoint.checkpointIndex] = saveCheckpoint;
            }
        }
        Debug.Log("On scene loaded");
    }

    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.F9)) StartCoroutine(LoadGame());
    }

    public void SaveGame(float health, int[] ammo, Vector3 position, int scene, Save_Checkpoint[] checkpoints)
    {
        DataSerializer.Save(SAVE_KEY, new SaveData(health, ammo, position, scene, checkpoints));
    }

    public IEnumerator LoadGame()
    {
        if (DataSerializer.TryLoad<SaveData>(SAVE_KEY, out var loadedData))
        {
            AsyncOperation asyncLoadLevel = SceneManager.LoadSceneAsync(loadedData.CurrentScene, LoadSceneMode.Single);
            while (!asyncLoadLevel.isDone) yield return null;
            yield return new WaitForEndOfFrame();

            player.transform.position = loadedData.Position;
            playerHealth.playerHealth = loadedData.Health;
            playerAmmoCounter.SetAmmo(loadedData.Ammo);
            currentCheckpoints = loadedData.Checkpoints;
            Debug.Log("Finished loading");
        }
    }
}

public struct SaveData
{
    [SerializeField] private float _health;
    [SerializeField] private int[] _ammo;
    [SerializeField] private Vector3 _position;
    [SerializeField] private int _currentScene;
    [SerializeField] private Save_Checkpoint[] _checkpoints;

    public float Health => _health;
    public int[] Ammo => _ammo;
    public Vector3 Position => _position;
    public int CurrentScene => _currentScene;
    public Save_Checkpoint[] Checkpoints => _checkpoints;

    public SaveData(float health, int[] ammo, Vector3 position, int currentScene, Save_Checkpoint[] checkpoints)
    {
        _health = health;
        _ammo = ammo;
        _position = position;
        _currentScene = currentScene;
        _checkpoints = checkpoints;
    }
}