using UnityEngine;

public static class GameSaveManager {
    private const string SaveKey = "UniRun.SaveData.v1";
    private const string LegacyTotalMileageKey = "UniRun.TotalMileage";

    public static GameSaveData Load() {
        if(PlayerPrefs.HasKey(SaveKey))
        {
            string json = PlayerPrefs.GetString(SaveKey);
            GameSaveData loadedData = JsonUtility.FromJson<GameSaveData>(json);

            if(loadedData != null)
            {
                Normalize(loadedData);
                return loadedData;
            }
        }

        GameSaveData saveData = GameSaveData.CreateDefault();
        saveData.totalMileage = PlayerPrefs.GetInt(LegacyTotalMileageKey, 0);
        Normalize(saveData);
        Save(saveData);
        return saveData;
    }

    public static void Save(GameSaveData saveData) {
        Normalize(saveData);
        string json = JsonUtility.ToJson(saveData);
        PlayerPrefs.SetString(SaveKey, json);
        PlayerPrefs.SetInt(LegacyTotalMileageKey, saveData.totalMileage);
        PlayerPrefs.Save();
    }

    public static GameSaveData ResetSave() {
        PlayerPrefs.DeleteKey(SaveKey);
        GameSaveData saveData = GameSaveData.CreateDefault();
        Save(saveData);
        return saveData;
    }

    public static void AddMileage(GameSaveData saveData, int amount) {
        if(saveData == null)
        {
            return;
        }

        saveData.totalMileage = Mathf.Max(0, saveData.totalMileage + amount);
        Save(saveData);
    }

    public static void UnlockMap(GameSaveData saveData, MapId mapId) {
        if(saveData == null)
        {
            return;
        }

        int mapIndex = MapDatabase.GetIndex(mapId);
        saveData.unlockedMapIndex = Mathf.Max(saveData.unlockedMapIndex, mapIndex);
        Save(saveData);
    }

    private static void Normalize(GameSaveData saveData) {
        saveData.currentMapIndex = Mathf.Clamp(saveData.currentMapIndex, 0, MapDatabase.LastMapIndex);
        saveData.unlockedMapIndex = Mathf.Clamp(saveData.unlockedMapIndex, 0, MapDatabase.LastMapIndex);
        saveData.currentMapIndex = Mathf.Min(saveData.currentMapIndex, saveData.unlockedMapIndex);
        saveData.totalMileage = Mathf.Max(0, saveData.totalMileage);
        saveData.bagSlots = Mathf.Clamp(saveData.bagSlots, 1, 3);
        saveData.shieldStock = Mathf.Max(0, saveData.shieldStock);
        saveData.lunchboxStock = Mathf.Max(0, saveData.lunchboxStock);
        saveData.speedShoesStock = Mathf.Max(0, saveData.speedShoesStock);
        saveData.mileageCardStock = Mathf.Max(0, saveData.mileageCardStock);
        saveData.bestScore = Mathf.Max(0, saveData.bestScore);
    }
}
