using System;
using System.IO;
using ZB.MOM.WW.CBDD.Bson;
using ZB.MOM.WW.CBDD.Shared;
using Xunit;

namespace ZB.MOM.WW.CBDD.Tests;

public class DbContextInheritanceTests : IDisposable
{
    private readonly string _dbPath;
    private readonly Shared.TestExtendedDbContext _db;

    /// <summary>
    /// Initializes a new instance of the <see cref="DbContextInheritanceTests"/> class.
    /// </summary>
    public DbContextInheritanceTests()
    {
        _dbPath = Path.Combine(Path.GetTempPath(), $"cbdd_inheritance_{Guid.NewGuid()}.db");
        _db = new Shared.TestExtendedDbContext(_dbPath);
    }

    /// <summary>
    /// Releases test resources.
    /// </summary>
    public void Dispose()
    {
        _db.Dispose();
        if (File.Exists(_dbPath)) File.Delete(_dbPath);
    }

    /// <summary>
    /// Verifies parent collections are initialized in the extended context.
    /// </summary>
    [Fact]
    public void ExtendedContext_Should_Initialize_Parent_Collections()
    {
        // Verify parent collections are initialized (from TestDbContext)
        _db.Users.ShouldNotBeNull();
        _db.People.ShouldNotBeNull();
        _db.Products.ShouldNotBeNull();
        _db.AnnotatedUsers.ShouldNotBeNull();
        _db.ComplexDocuments.ShouldNotBeNull();
        _db.TestDocuments.ShouldNotBeNull();
    }

    /// <summary>
    /// Verifies extended context collections are initialized.
    /// </summary>
    [Fact]
    public void ExtendedContext_Should_Initialize_Own_Collections()
    {
        // Verify extended context's own collection is initialized
        _db.ExtendedEntities.ShouldNotBeNull();
    }

    /// <summary>
    /// Verifies parent collections are usable from the extended context.
    /// </summary>
    [Fact]
    public void ExtendedContext_Can_Use_Parent_Collections()
    {
        // Insert into parent collection
        var user = new User { Name = "TestUser", Age = 30 };
        _db.Users.Insert(user);
        _db.SaveChanges();

        // Verify we can read it back
        var retrieved = _db.Users.FindById(user.Id);
        retrieved.ShouldNotBeNull();
        retrieved.Name.ShouldBe("TestUser");
        retrieved.Age.ShouldBe(30);
    }

    /// <summary>
    /// Verifies extended collections are usable from the extended context.
    /// </summary>
    [Fact]
    public void ExtendedContext_Can_Use_Own_Collections()
    {
        // Insert into extended collection
        var entity = new ExtendedEntity
        {
            Id = 1,
            Description = "Test Extended Entity",
            CreatedAt = DateTime.UtcNow
        };
        _db.ExtendedEntities.Insert(entity);
        _db.SaveChanges();

        // Verify we can read it back
        var retrieved = _db.ExtendedEntities.FindById(1);
        retrieved.ShouldNotBeNull();
        retrieved.Description.ShouldBe("Test Extended Entity");
    }

    /// <summary>
    /// Verifies parent and extended collections can be used together.
    /// </summary>
    [Fact]
    public void ExtendedContext_Can_Use_Both_Parent_And_Own_Collections()
    {
        // Insert into parent collection
        var person = new Person { Id = 100, Name = "John", Age = 25 };
        _db.People.Insert(person);

        // Insert into extended collection
        var extended = new ExtendedEntity
        {
            Id = 200,
            Description = "Related to John",
            CreatedAt = DateTime.UtcNow
        };
        _db.ExtendedEntities.Insert(extended);

        _db.SaveChanges();

        // Verify both
        var retrievedPerson = _db.People.FindById(100);
        var retrievedExtended = _db.ExtendedEntities.FindById(200);

        retrievedPerson.ShouldNotBeNull();
        retrievedPerson.Name.ShouldBe("John");

        retrievedExtended.ShouldNotBeNull();
        retrievedExtended.Description.ShouldBe("Related to John");
    }
}
