using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using YachtDice.Modifiers.Runtime;
using YachtDice.Persistence;

namespace YachtDice.Tests
{
    public class SaveSystemTests
    {
        [SetUp]
        public void SetUp()
        {
            SaveSystem.Delete();
        }

        [TearDown]
        public void TearDown()
        {
            SaveSystem.Delete();
        }

        [Test]
        public void SaveAndLoad_RoundTrip_PreservesData()
        {
            var data = new SaveData
            {
                Currency = 999,
                OwnedModifiers = new List<ModifierSaveEntry>
                {
                    new() { ModifierId = "mod1", IsActive = true, RemainingUses = 3 },
                    new() { ModifierId = "mod2", IsActive = false, RemainingUses = -1 }
                }
            };

            SaveSystem.Save(data);
            var loaded = SaveSystem.Load();

            Assert.AreEqual(999, loaded.Currency);
            Assert.AreEqual(2, loaded.OwnedModifiers.Count);
            Assert.AreEqual("mod1", loaded.OwnedModifiers[0].ModifierId);
            Assert.IsTrue(loaded.OwnedModifiers[0].IsActive);
            Assert.AreEqual(3, loaded.OwnedModifiers[0].RemainingUses);
            Assert.AreEqual("mod2", loaded.OwnedModifiers[1].ModifierId);
            Assert.IsFalse(loaded.OwnedModifiers[1].IsActive);
        }

        [Test]
        public void Load_MissingKey_ReturnsDefault()
        {
            var loaded = SaveSystem.Load();

            Assert.IsNotNull(loaded);
            Assert.AreEqual(0, loaded.Currency);
            Assert.AreEqual(0, loaded.OwnedModifiers.Count);
        }

        [Test]
        public void HasSave_ReturnsFalseWhenEmpty()
        {
            Assert.IsFalse(SaveSystem.HasSave());
        }

        [Test]
        public void HasSave_ReturnsTrueAfterSave()
        {
            SaveSystem.Save(new SaveData { Currency = 100 });

            Assert.IsTrue(SaveSystem.HasSave());
        }

        [Test]
        public void Delete_RemovesSaveData()
        {
            SaveSystem.Save(new SaveData { Currency = 100 });
            SaveSystem.Delete();

            Assert.IsFalse(SaveSystem.HasSave());
        }

        [Test]
        public void Load_CorruptJson_ReturnsDefault()
        {
            PlayerPrefs.SetString("YachtDice_SaveData", "{invalid json!!!");
            PlayerPrefs.Save();

            var loaded = SaveSystem.Load();

            Assert.IsNotNull(loaded);
            Assert.AreEqual(0, loaded.Currency);
        }

        [Test]
        public void SaveAndLoad_RoundTrip_PreservesDiceIds()
        {
            var data = new SaveData
            {
                Currency = 100,
                OwnedDiceIds = new List<string> { "standard_d6", "chaos_d6" }
            };

            SaveSystem.Save(data);
            var loaded = SaveSystem.Load();

            Assert.AreEqual(2, loaded.OwnedDiceIds.Count);
            Assert.AreEqual("standard_d6", loaded.OwnedDiceIds[0]);
            Assert.AreEqual("chaos_d6", loaded.OwnedDiceIds[1]);
        }
    }
}
