using ZB.MOM.WW.CBDD.Shared;

namespace ZB.MOM.WW.CBDD.Tests
{
    /// <summary>
    /// Tests for entities with nullable string Id (like UuidEntity scenario from CleanCore)
    /// This reproduces the bug where the generator incorrectly chose ObjectIdMapperBase 
    /// instead of StringMapperBase for inherited nullable string Id properties
    /// </summary>
    public class NullableStringIdTests : System.IDisposable
    {
        private const string DbPath = "nullable_string_id.db";

        /// <summary>
        /// Initializes a new instance of the <see cref="NullableStringIdTests"/> class.
        /// </summary>
        public NullableStringIdTests()
        {
            if (File.Exists(DbPath)) File.Delete(DbPath);
        }

        /// <summary>
        /// Disposes test resources.
        /// </summary>
        public void Dispose()
        {
            if (File.Exists(DbPath)) File.Delete(DbPath);
        }

        /// <summary>
        /// Verifies the mock counter collection is initialized.
        /// </summary>
        [Fact]
        public void MockCounter_Collection_IsInitialized()
        {
            using var db = new Shared.TestDbContext(DbPath);

            // Verify Collection is not null (initialized by generated method)
            db.MockCounters.ShouldNotBeNull();
        }

        /// <summary>
        /// Verifies insert and find-by-id operations work for string identifiers.
        /// </summary>
        [Fact]
        public void MockCounter_Insert_And_FindById_Works()
        {
            using var db = new Shared.TestDbContext(DbPath);

            var counter = new MockCounter("test-id-123")
            {
                Name = "TestCounter",
                Value = 42
            };

            // Insert should work with string Id
            db.MockCounters.Insert(counter);

            // FindById should retrieve the entity
            var stored = db.MockCounters.FindById("test-id-123");
            stored.ShouldNotBeNull();
            stored.Id.ShouldBe("test-id-123");
            stored.Name.ShouldBe("TestCounter");
            stored.Value.ShouldBe(42);
        }

        /// <summary>
        /// Verifies update operations work for string identifiers.
        /// </summary>
        [Fact]
        public void MockCounter_Update_Works()
        {
            using var db = new Shared.TestDbContext(DbPath);

            var counter = new MockCounter("update-test")
            {
                Name = "Original",
                Value = 10
            };

            db.MockCounters.Insert(counter);

            // Update the entity
            counter.Name = "Updated";
            counter.Value = 20;
            db.MockCounters.Update(counter);

            // Verify update
            var updated = db.MockCounters.FindById("update-test");
            updated.ShouldNotBeNull();
            updated.Name.ShouldBe("Updated");
            updated.Value.ShouldBe(20);
        }

        /// <summary>
        /// Verifies delete operations work for string identifiers.
        /// </summary>
        [Fact]
        public void MockCounter_Delete_Works()
        {
            using var db = new Shared.TestDbContext(DbPath);

            var counter = new MockCounter("delete-test")
            {
                Name = "ToDelete",
                Value = 99
            };

            db.MockCounters.Insert(counter);
            db.MockCounters.FindById("delete-test").ShouldNotBeNull();

            // Delete the entity
            db.MockCounters.Delete("delete-test");

            // Verify deletion
            var deleted = db.MockCounters.FindById("delete-test");
            deleted.ShouldBeNull();
        }

        /// <summary>
        /// Verifies query operations work for string identifiers.
        /// </summary>
        [Fact]
        public void MockCounter_Query_Works()
        {
            using var db = new Shared.TestDbContext(DbPath);

            db.MockCounters.Insert(new MockCounter("q1") { Name = "First", Value = 100 });
            db.MockCounters.Insert(new MockCounter("q2") { Name = "Second", Value = 200 });
            db.MockCounters.Insert(new MockCounter("q3") { Name = "Third", Value = 150 });

            // Query all
            var all = db.MockCounters.AsQueryable().ToList();
            all.Count.ShouldBe(3);

            // Query with condition
            var highValues = db.MockCounters.AsQueryable()
                .Where(c => c.Value > 150)
                .ToList();

            highValues.Count().ShouldBe(1);
            highValues[0].Name.ShouldBe("Second");
        }

        /// <summary>
        /// Verifies inherited string identifiers are stored and retrieved correctly.
        /// </summary>
        [Fact]
        public void MockCounter_InheritedId_IsStoredCorrectly()
        {
            using var db = new Shared.TestDbContext(DbPath);

            // Test that the inherited nullable string Id from MockBaseEntity works correctly
            var counter = new MockCounter("inherited-id-test")
            {
                Name = "Inherited",
                Value = 777
            };

            db.MockCounters.Insert(counter);

            var stored = db.MockCounters.FindById("inherited-id-test");
            stored.ShouldNotBeNull();

            // Verify the Id is correctly stored and retrieved through inheritance
            stored.Id.ShouldBe("inherited-id-test");
            stored.Id.ShouldBeOfType<string>();
        }
    }
}
