using System.Net;
using System.Net.Http.Json;
using CashLineERP.Contracts.External;
using CashLineERP.Contracts.Parties;
using CashLineERP.Infrastructure.Persistence;
using Microsoft.Extensions.DependencyInjection;

namespace CashLineERP.Api.Tests;

public sealed class PublicOnboardingQaTests : IClassFixture<ApiTestFactory>
{
    private readonly HttpClient _client;
    private readonly ApiTestFactory _factory;

    public PublicOnboardingQaTests(ApiTestFactory factory)
    {
        _factory = factory;
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task Public_Supplier_Onboarding_Creates_Submitted_Profile_And_Workflow()
    {
        var response = await _client.PostAsJsonAsync("/api/v1/public/onboarding/suppliers", new CreatePublicSupplierOnboardingApplicationRequest(
            null,
            "Public Supplier One",
            "EG",
            null,
            "TAX-SUP-PUBLIC-001",
            "001",
            "supplier.public@example.com",
            "+201000000401",
            "Cairo",
            "LOCAL_VENDOR",
            "EGP",
            "BANK_TRANSFER",
            30,
            7,
            2500m,
            "Banque Misr",
            "4455667788990011",
            "BMISEGCX",
            "Self-initiated onboarding",
            [
                new RecordBusinessPartyComplianceDocumentRequest(
                    "COMMERCIAL_REGISTER",
                    "commercial-register.pdf",
                    "managed://public-onboarding/supplier/commercial-register.pdf",
                    "application/pdf",
                    2048)
            ]));

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        var payload = await response.Content.ReadFromJsonAsync<PublicSupplierOnboardingApplicationResponse>();
        Assert.NotNull(payload);
        Assert.Equal("SUBMITTED", payload!.StatusCode);
        Assert.Equal(1, payload.ComplianceDocumentCount);

        using var scope = _factory.Services.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<CashLineErpDbContext>();

        var workflow = dbContext.WorkflowInstances.Single(entry =>
            entry.DocumentType == "SUPPLIER_PROFILE"
            && entry.DocumentId == payload.SupplierProfileId);

        Assert.Equal("SUBMITTED", workflow.CurrentStatusCode);
        Assert.Equal(0, workflow.MakerUserId);
    }

    [Fact]
    public async Task Public_Customer_Onboarding_Creates_Submitted_Profile_And_Workflow()
    {
        var response = await _client.PostAsJsonAsync("/api/v1/public/onboarding/customers", new CreatePublicCustomerOnboardingApplicationRequest(
            null,
            "Public Customer One",
            "EG",
            null,
            "TAX-CUS-PUBLIC-001",
            "001",
            "customer.public@example.com",
            "+201000000402",
            "Alexandria",
            50000m,
            45,
            false,
            null,
            "COMPANY",
            "WHOLESALE",
            "EGP",
            "DIRECT_SALES",
            "STANDARD",
            "EMAIL",
            "Self-initiated customer onboarding",
            [
                new RecordBusinessPartyComplianceDocumentRequest(
                    "VAT_CERTIFICATE",
                    "vat-certificate.pdf",
                    "managed://public-onboarding/customer/vat-certificate.pdf",
                    "application/pdf",
                    2048)
            ]));

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        var payload = await response.Content.ReadFromJsonAsync<PublicCustomerOnboardingApplicationResponse>();
        Assert.NotNull(payload);
        Assert.Equal("SUBMITTED", payload!.StatusCode);
        Assert.Equal(1, payload.ComplianceDocumentCount);

        using var scope = _factory.Services.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<CashLineErpDbContext>();

        var workflow = dbContext.WorkflowInstances.Single(entry =>
            entry.DocumentType == "CUSTOMER_PROFILE"
            && entry.DocumentId == payload.CustomerProfileId);

        Assert.Equal("SUBMITTED", workflow.CurrentStatusCode);
        Assert.Equal(0, workflow.MakerUserId);
    }
}
