using NUnit.Framework;
using Core.Domain;
using Infrastructure.Unity;

namespace DecayGrid.Tests
{
    public class TileRegistryTests
    {
        private TileRegistry _registry;

        [SetUp]
        public void SetUp() => _registry = new TileRegistry();

        [Test]
        public void Register_AddsToAllTiles()
        {
            var tile = new Tile("0_0_0", 0, 0.5f, 2f);
            _registry.Register(tile);
            Assert.AreEqual(1, _registry.AllTiles.Count);
        }

        [Test]
        public void FindTiles_ReturnsMatchingTiles()
        {
            var tile = new Tile("0_0_0", 0, 0.5f, 2f);
            _registry.Register(tile);
            var result = _registry.FindTiles(t => t.CurrentState == TileState.Stable);
            Assert.AreEqual(1, result.Count);
        }

        [Test]
        public void FindTiles_ExcludesNonMatchingTiles()
        {
            var tile = new Tile("0_0_0", 0, 0.5f, 2f);
            tile.StepOn(); // Now Warning
            _registry.Register(tile);
            var result = _registry.FindTiles(t => t.CurrentState == TileState.Stable);
            Assert.AreEqual(0, result.Count);
        }

        [Test]
        public void TryGetView_ReturnsFalse_WhenTileHasNoView()
        {
            var tile = new Tile("0_0_0", 0, 0.5f, 2f);
            _registry.Register(tile); // no view
            Assert.IsFalse(_registry.TryGetView("0_0_0", out _));
        }

        [Test]
        public void GroupViewsByFloor_PlacesTileOnCorrectFloor()
        {
            // Can't create TileViewAdapter in EditMode (MonoBehaviour), so just verify tile with no view doesn't crash
            var tile = new Tile("1_5_5", 1, 0.5f, 2f);
            _registry.Register(tile); // no view
            var floors = _registry.GroupViewsByFloor(3);
            Assert.AreEqual(3, floors.Count);
            // Tile has no view registered, so no view should appear in any floor
            Assert.AreEqual(0, floors[1].Count);
        }

        [Test]
        public void GroupViewsByFloor_OutOfRangeTile_DoesNotThrow()
        {
            var tile = new Tile("5_0_0", 5, 0.5f, 2f); // floor 5, but only 3 floors
            _registry.Register(tile);
            Assert.DoesNotThrow(() => _registry.GroupViewsByFloor(3));
        }
    }
}
