using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class SaveSystemManager : MonoBehaviour
{
    private FogOfWar fogOfWar;
    private GenerateTileMap generateTileMap;
    private PlayerController playerController;
    private Inventory playerInventory;
    private SaveDataMap mapState;
    private SaveDataPlayer playerState;
    public static SaveSystemManager Instance { get; private set; }
    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            fogOfWar = FindObjectOfType<FogOfWar>();
            generateTileMap = FindObjectOfType<GenerateTileMap>();
            playerController = GameObject.Find("Player").GetComponent<PlayerController>();
            playerInventory = GameObject.Find("Player").GetComponent<Inventory>();
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void SaveGame()
    {
        SaveSystem.SavePlayer(GetSaveDataPlayer());
        SaveSystem.SaveMapState(GetSaveDataMap());
    }

    private SaveDataPlayer GetSaveDataPlayer()
    {
        return new SaveDataPlayer(playerController, playerInventory);
    }

    public SaveDataMap GetMapStateFromSave()
    {
        if (mapState == null)
        {
            mapState = SaveSystem.LoadMapState();
        }
        return mapState;
    }

    public SaveDataPlayer GetPlayerStateFromSave()
    {
        if (playerState == null)
        {
            playerState = SaveSystem.LoadPlayer();
            Debug.Log("Player state loaded from save");
        }
        return playerState;
    }

    private SaveDataMap GetSaveDataMap()
    {
        var saveDataTileMap = GetSaveDataTileMap();
        return new SaveDataMap(
            saveDataTileMap.seed,
            saveDataTileMap.destroyedTiles,
            saveDataTileMap.chunkCache,
            GetSaveDataFogOfWar()
        );
    }

    private FogOfWarData GetSaveDataFogOfWar()
    {
        var fogSaveValues = fogOfWar.GetSaveValues();
        FogOfWarData saveData = new FogOfWarData();

        for (int x = 0; x < fogSaveValues.discoveredFog.GetLength(0); x++)
        {
            for (int y = 0; y < fogSaveValues.discoveredFog.GetLength(1); y++)
            {
                TileBase currentTile = fogSaveValues.discoveredFog[x, y];
                if (currentTile == null || currentTile != fogSaveValues.fogTile) // Only save revealed tiles
                {
                    FogTileData tileData = new FogTileData
                    {
                        x = x,
                        y = y,
                        fogLevelIndex = currentTile == null ? -1 : System.Array.FindIndex(fogSaveValues.fogLevels, f => f.tile == currentTile)
                    };
                    saveData.discoveredTiles.Add(tileData);
                }
            }
        }

        return saveData;
    }

    public (int seed, Dictionary<Vector2Int, TileBase[]> chunkCache, List<Vector3Int> destroyedTiles) GetSaveDataTileMap()
    {
        return generateTileMap.GetSaveValues();
    }
}