using ZB.MOM.WW.CBDD.Bson;
using ZB.MOM.WW.CBDD.Core;
using ZB.MOM.WW.CBDD.Core.Collections;
using ZB.MOM.WW.CBDD.Core.Metadata;
using ZB.MOM.WW.CBDD.Shared;
using System;
using System.Buffers;

namespace ZB.MOM.WW.CBDD.Tests;

public class PrimaryKeyTests : IDisposable
{
    private readonly string _dbPath = "primary_key_tests.db";

    public PrimaryKeyTests()
    {
        if (File.Exists(_dbPath)) File.Delete(_dbPath);
    }

    public void Dispose()
    {
        if (File.Exists(_dbPath)) File.Delete(_dbPath);
    }

    [Fact]
    public void Test_Int_PrimaryKey()
    {
        using var db = new Shared.TestDbContext(_dbPath);

        var entity = new IntEntity { Id = 1, Name = "Test 1" };
        db.IntEntities.Insert(entity);
        db.SaveChanges();

        var retrieved = db.IntEntities.FindById(1);
        retrieved.ShouldNotBeNull();
        retrieved.Id.ShouldBe(1);
        retrieved.Name.ShouldBe("Test 1");

        entity.Name = "Updated";
        db.IntEntities.Update(entity);

        retrieved = db.IntEntities.FindById(1);
        retrieved?.Name.ShouldBe("Updated");

        db.IntEntities.Delete(1);
        db.IntEntities.FindById(1).ShouldBeNull();
    }

    [Fact]
    public void Test_String_PrimaryKey()
    {
        using var db = new Shared.TestDbContext(_dbPath);

        var entity = new StringEntity { Id = "key1", Value = "Value 1" };
        db.StringEntities.Insert(entity);
        db.SaveChanges();

        var retrieved = db.StringEntities.FindById("key1");
        retrieved.ShouldNotBeNull();
        retrieved.Id.ShouldBe("key1");
        retrieved.Value.ShouldBe("Value 1");

        db.StringEntities.Delete("key1");
        db.SaveChanges();
        db.StringEntities.FindById("key1").ShouldBeNull();
    }

    [Fact]
    public void Test_Guid_PrimaryKey()
    {
        using var db = new Shared.TestDbContext(_dbPath);

        var id = Guid.NewGuid();
        var entity = new GuidEntity { Id = id, Name = "Guid Test" };
        db.GuidEntities.Insert(entity);
        db.SaveChanges();

        var retrieved = db.GuidEntities.FindById(id);
        retrieved.ShouldNotBeNull();
        retrieved.Id.ShouldBe(id);

        db.GuidEntities.Delete(id);
        db.SaveChanges();
        db.GuidEntities.FindById(id).ShouldBeNull();
    }

    [Fact]
    public void Test_String_PrimaryKey_With_Custom_Name()
    {
        // Test entity with string key NOT named "Id" (named "Code" instead)
        using var db = new Shared.TestDbContext(_dbPath);

        var entity = new CustomKeyEntity { Code = "ABC123", Description = "Test Description" };
        db.CustomKeyEntities.Insert(entity);
        db.SaveChanges();

        // Verify retrieval works correctly
        var retrieved = db.CustomKeyEntities.FindById("ABC123");
        retrieved.ShouldNotBeNull();
        retrieved.Code.ShouldBe("ABC123");
        retrieved.Description.ShouldBe("Test Description");

        // Verify update works
        entity.Description = "Updated Description";
        db.CustomKeyEntities.Update(entity);
        db.SaveChanges();

        retrieved = db.CustomKeyEntities.FindById("ABC123");
        retrieved?.Description.ShouldBe("Updated Description");

        // Verify delete works
        db.CustomKeyEntities.Delete("ABC123");
        db.SaveChanges();
        db.CustomKeyEntities.FindById("ABC123").ShouldBeNull();
    }
}
