using CashLineERP.Application.Finance;
using CashLineERP.Contracts.Finance;
using CashLineERP.Infrastructure.Persistence.Repositories;

namespace CashLineERP.Api.Tests;

public sealed class CardTokenReferenceServiceQaTests
{
    [Fact]
    public void Card_Token_Reference_Default_Switching_Preserves_Only_One_Default_Per_Party_Provider_And_Usage()
    {
        using var dbContext = QaDbContextFactory.CreateContext();
        var service = new CardTokenReferenceService(new CardTokenReferenceRepository(dbContext));

        var first = service.CreateCardTokenReference(new CreateCardTokenReferenceRequest(
            PartyId: 2,
            PartyTypeCode: "CUSTOMER",
            IntegrationProviderCode: "PAYMOB",
            UsageCode: "CUSTOMER_COLLECTION",
            CardBrandCode: "VISA",
            MaskedPan: "4111********1111",
            ExpiryMonth: 12,
            ExpiryYear: 2028,
            TokenReference: "tok_paymob_001",
            ExternalCustomerReference: "cust_paymob_001",
            IsDefault: true,
            Notes: "Primary saved card"));
        service.SubmitCardTokenReference(first.CardTokenReferenceId, 3);
        service.ApproveCardTokenReference(first.CardTokenReferenceId, 4);
        service.ActivateCardTokenReference(first.CardTokenReferenceId, 4);

        var second = service.CreateCardTokenReference(new CreateCardTokenReferenceRequest(
            PartyId: 2,
            PartyTypeCode: "CUSTOMER",
            IntegrationProviderCode: "PAYMOB",
            UsageCode: "CUSTOMER_COLLECTION",
            CardBrandCode: "MASTERCARD",
            MaskedPan: "5555********4444",
            ExpiryMonth: 11,
            ExpiryYear: 2029,
            TokenReference: "tok_paymob_002",
            ExternalCustomerReference: "cust_paymob_001",
            IsDefault: true,
            Notes: "Replacement default card"));
        service.SubmitCardTokenReference(second.CardTokenReferenceId, 3);
        service.ApproveCardTokenReference(second.CardTokenReferenceId, 4);
        var activatedSecond = service.ActivateCardTokenReference(second.CardTokenReferenceId, 4);

        var references = service.GetCardTokenReferences(activeOnly: true, partyId: 2, integrationProviderCode: "PAYMOB", usageCode: "CUSTOMER_COLLECTION");
        Assert.Equal(2, references.Count);
        var defaultReference = Assert.Single(references, entry => entry.IsDefault);
        Assert.Equal(activatedSecond.CardTokenReferenceId, defaultReference.CardTokenReferenceId);
    }

    [Fact]
    public void Card_Token_Reference_Maker_Checker_Blocks_Self_Approval()
    {
        using var dbContext = QaDbContextFactory.CreateContext();
        var service = new CardTokenReferenceService(new CardTokenReferenceRepository(dbContext));

        var created = service.CreateCardTokenReference(new CreateCardTokenReferenceRequest(
            PartyId: 2,
            PartyTypeCode: "CUSTOMER",
            IntegrationProviderCode: "PAYMOB",
            UsageCode: "CUSTOMER_COLLECTION",
            CardBrandCode: "VISA",
            MaskedPan: "4111********9999",
            ExpiryMonth: 10,
            ExpiryYear: 2027,
            TokenReference: "tok_paymob_self",
            ExternalCustomerReference: "cust_paymob_self",
            IsDefault: false,
            Notes: "Maker-checker QA"));
        service.SubmitCardTokenReference(created.CardTokenReferenceId, 3);

        var exception = Assert.Throws<InvalidOperationException>(() =>
            service.ApproveCardTokenReference(created.CardTokenReferenceId, 3));

        Assert.Contains("maker-checker", exception.Message, StringComparison.OrdinalIgnoreCase);
    }
}
