using System.Collections.Generic;
using NUnit.Framework;
using YachtDice.Dice;
using YachtDice.Player;

namespace YachtDice.Tests
{
    public sealed class DiceCollectionTests
    {
        private DiceCollection collection;

        [SetUp]
        public void SetUp()
        {
            collection = new DiceCollection();
        }

        [Test]
        public void Add_IncreasesCount()
        {
            var die = StandardDieSO.CreateStandardD6ForTest();

            collection.Add(die);

            Assert.AreEqual(1, collection.OwnedDice.Count);
        }

        [Test]
        public void Add_DuplicateId_Ignored()
        {
            var die = StandardDieSO.CreateStandardD6ForTest();

            collection.Add(die);
            collection.Add(die);

            Assert.AreEqual(1, collection.OwnedDice.Count);
        }

        [Test]
        public void Add_Null_Ignored()
        {
            collection.Add(null);

            Assert.AreEqual(0, collection.OwnedDice.Count);
        }

        [Test]
        public void OwnsById_ReturnsTrueWhenOwned()
        {
            var die = StandardDieSO.CreateStandardD6ForTest();

            collection.Add(die);

            Assert.IsTrue(collection.OwnsById("standard_d6"));
        }

        [Test]
        public void OwnsById_ReturnsFalseWhenNotOwned()
        {
            Assert.IsFalse(collection.OwnsById("standard_d6"));
        }

        [Test]
        public void Remove_DecreasesCount()
        {
            var die = StandardDieSO.CreateStandardD6ForTest();

            collection.Add(die);
            collection.Remove(die);

            Assert.AreEqual(0, collection.OwnedDice.Count);
        }

        [Test]
        public void GetSaveData_ReturnsIds()
        {
            var die = StandardDieSO.CreateStandardD6ForTest();

            collection.Add(die);

            var ids = collection.GetSaveData();
            Assert.AreEqual(1, ids.Count);
            Assert.AreEqual("standard_d6", ids[0]);
        }

        [Test]
        public void LoadSaveData_RestoresDice()
        {
            var die = StandardDieSO.CreateStandardD6ForTest();
            var catalog = DiceCatalog.CreateForTest(new List<DieDefinitionSO> { die });
            var ids = new List<string> { "standard_d6" };

            collection.LoadSaveData(ids, catalog);

            Assert.AreEqual(1, collection.OwnedDice.Count);
            Assert.AreEqual("standard_d6", collection.OwnedDice[0].Id);
        }

        [Test]
        public void LoadSaveData_SkipsMissingIds()
        {
            var catalog = DiceCatalog.CreateForTest(new List<DieDefinitionSO>());
            var ids = new List<string> { "nonexistent" };

            collection.LoadSaveData(ids, catalog);

            Assert.AreEqual(0, collection.OwnedDice.Count);
        }

        [Test]
        public void Clear_RemovesAll()
        {
            var die = StandardDieSO.CreateStandardD6ForTest();

            collection.Add(die);
            collection.Clear();

            Assert.AreEqual(0, collection.OwnedDice.Count);
        }

        [Test]
        public void Add_FiresOnChanged()
        {
            bool fired = false;
            collection.OnChanged += () => fired = true;

            var die = StandardDieSO.CreateStandardD6ForTest();
            collection.Add(die);

            Assert.IsTrue(fired);
        }
    }
}
