using Baya.Infrastructure.Persistence.Services.Configuration;

namespace Baya.Test.Foundation.Marketplace;

public sealed class PlatformConfigServiceTests
{
    [Fact]
    public async Task GetConfig_ParsesValueByDataType()
    {
        using var host = new OpsTestHost();
        var config = new PlatformConfigService(host.Db, host.Cache);

        Assert.Equal(0.10m, await config.GetConfig<decimal>("vat_rate"));
        Assert.Equal(72, await config.GetConfig<int>("dispute_window_hours"));
        Assert.Equal(30, await config.GetConfig<int>("booking_payment_deadline_minutes"));
        Assert.Equal("platform", await config.GetConfig<string>("bnpl_merchant_of_record"));
    }

    [Fact]
    public async Task SetConfig_UpdatesValue_WritesAuditRow_AndEvictsCache()
    {
        using var host = new OpsTestHost();
        host.CurrentUser.UserId = await host.AddUserAsync("admin");
        var config = new PlatformConfigService(host.Db, host.Cache);

        // Prime the cache with the seeded value.
        Assert.Equal(0.15m, await config.GetConfig<decimal>("platform_fee_rate"));

        var updated = await config.SetConfig("platform_fee_rate", "0.18");
        Assert.True(updated);

        // Cache was evicted → the next read returns the new value.
        Assert.Equal(0.18m, await config.GetConfig<decimal>("platform_fee_rate"));

        var history = await config.GetConfigChangeHistory("platform_fee_rate", 1, 20);
        Assert.Equal(1, history.Total);
        var change = Assert.Single(history.Items);
        Assert.Equal("updated", change.Action);
        Assert.Equal(host.CurrentUser.UserId, change.ActorUserId);
        Assert.Contains("0.15", change.ChangedFieldsJson);
        Assert.Contains("0.18", change.ChangedFieldsJson);
    }

    [Fact]
    public async Task SetConfig_MissingKey_ReturnsFalse()
    {
        using var host = new OpsTestHost();
        var config = new PlatformConfigService(host.Db, host.Cache);

        Assert.False(await config.SetConfig("does_not_exist", "x"));
    }
}
