using System.Text.Json;
using FluentAssertions;
using foodmarket.Shared.Pos.V1;
using Xunit;

namespace foodmarket.UnitTests;

/// <summary>Контракт POS — public API: ломая его, мы ломаем все Windows-кассы
/// в поле. Тестируем сериализацию round-trip + наличие required-полей.
/// При попытке убрать поле или поменять тип компиляция этих тестов упадёт.</summary>
public class PosContractsTests
{
    [Fact]
    public void Product_sync_dto_round_trips()
    {
        var dto = new ProductSyncDto
        {
            Id = Guid.NewGuid(),
            Name = "Молоко 1л",
            Article = "M-001",
            Barcodes = new[] { "1234567890123", "2345678901234" },
            UnitCode = "л",
            Packaging = 1,
            VatPercent = 12m,
            VatEnabled = true,
            IsMarked = false,
            IsArchived = false,
            UpdatedAt = DateTime.UtcNow,
        };
        var json = JsonSerializer.Serialize(dto);
        var back = JsonSerializer.Deserialize<ProductSyncDto>(json)!;
        back.Should().BeEquivalentTo(dto);
    }

    [Fact]
    public void Batch_dto_carries_idempotency_key()
    {
        var batch = new PosSaleBatchDto
        {
            IdempotencyKey = Guid.NewGuid(),
            Sales = new[]
            {
                new PosSaleDto
                {
                    ClientSaleId = Guid.NewGuid(),
                    OccurredAt = DateTime.UtcNow,
                    Payment = 0, PaidCash = 1000m, PaidCard = 0m,
                    Lines = new[]
                    {
                        new PosSaleLineDto
                        {
                            ProductId = Guid.NewGuid(), Quantity = 1m,
                            UnitPrice = 1000m, Discount = 0m, VatPercent = 12m,
                        },
                    },
                },
            },
        };
        var json = JsonSerializer.Serialize(batch);
        var back = JsonSerializer.Deserialize<PosSaleBatchDto>(json)!;
        back.IdempotencyKey.Should().Be(batch.IdempotencyKey);
        back.Sales.Should().HaveCount(1);
        back.Sales[0].Lines.Should().HaveCount(1);
    }

    [Fact]
    public void Sync_response_collects_all_groups()
    {
        var resp = new PosSyncResponse
        {
            ServerTime = DateTime.UtcNow,
            Products = Array.Empty<ProductSyncDto>(),
            Prices = Array.Empty<PriceSyncDto>(),
            Stocks = Array.Empty<StockSyncDto>(),
            Counterparties = Array.Empty<CounterpartySyncDto>(),
            DeletedProductIds = Array.Empty<Guid>(),
        };
        var json = JsonSerializer.Serialize(resp);
        var back = JsonSerializer.Deserialize<PosSyncResponse>(json)!;
        back.Should().BeEquivalentTo(resp);
    }
}
