using System.Net;
using System.Net.Http.Json;
using CashLineERP.Contracts.Parties;
using CashLineERP.Contracts.Suppliers;

namespace CashLineERP.Api.Tests;

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

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

    [Fact]
    public async Task Supplier_Onboarding_Review_Persists_Checklist_Items_And_Findings()
    {
        await _client.AuthenticateAsInternalAsync();

        var partyResponse = await _client.PostAsJsonAsync("/api/v1/parties", new CreateBusinessPartyRequest(
            $"SUP-REV-{Guid.NewGuid():N}"[..17].ToUpperInvariant(),
            "Review Supplier",
            "SUPPLIER",
            "EG",
            null,
            "HTTP-TAX-REV-001",
            "001",
            "supplier-review@example.com",
            "+201000000531",
            "Cairo",
            null,
            null,
            false,
            null));
        var party = await partyResponse.Content.ReadFromJsonAsync<BusinessPartyResponse>();
        Assert.NotNull(party);

        var complianceResponse = await _client.PostAsJsonAsync(
            $"/api/v1/parties/{party!.PartyId}/compliance-documents",
            new RecordBusinessPartyComplianceDocumentRequest(
                "COMMERCIAL_REGISTER",
                "commercial-register.pdf",
                "managed://supplier/review/commercial-register.pdf",
                "application/pdf",
                2048));
        Assert.Equal(HttpStatusCode.OK, complianceResponse.StatusCode);

        var createResponse = await _client.PostAsJsonAsync("/api/v1/suppliers", new CreateSupplierProfileRequest(
            party.PartyId,
            null,
            "LOCAL_VENDOR",
            "EGP",
            "BANK_TRANSFER",
            30,
            5,
            500m,
            "CIB",
            "1122334455667711",
            "CIBEEGCX",
            "Supplier onboarding review test"));
        var created = await createResponse.Content.ReadFromJsonAsync<SupplierProfileResponse>();
        Assert.NotNull(created);

        var submitResponse = await _client.PostAsync($"/api/v1/suppliers/{created!.SupplierProfileId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitResponse.StatusCode);

        var checklistResponse = await _client.PostAsJsonAsync(
            $"/api/v1/suppliers/{created.SupplierProfileId}/onboarding-review/checklist-items",
            new[]
            {
                new UpsertOnboardingReviewChecklistItemRequest(
                    "COMMERCIAL_REGISTRATION",
                    "Commercial Registration",
                    "ACCEPTED",
                    "PARTIAL",
                    "Readable and matched."),
                new UpsertOnboardingReviewChecklistItemRequest(
                    "BANK_CONFIRMATION",
                    "Bank Confirmation",
                    "MISSING",
                    "PARTIAL",
                    "Awaiting bank letter.")
            });
        Assert.Equal(HttpStatusCode.OK, checklistResponse.StatusCode);

        var findingResponse = await _client.PostAsJsonAsync(
            $"/api/v1/suppliers/{created.SupplierProfileId}/onboarding-review/findings",
            new CreateOnboardingReviewFindingRequest(
                "BANK_CONFIRMATION_PENDING",
                "MEDIUM",
                "BANK_CONFIRMATION",
                "OPEN",
                "Bank confirmation document still pending."));
        Assert.Equal(HttpStatusCode.OK, findingResponse.StatusCode);

        var reviewResponse = await _client.GetAsync($"/api/v1/suppliers/{created.SupplierProfileId}/onboarding-review");
        Assert.Equal(HttpStatusCode.OK, reviewResponse.StatusCode);
        var review = await reviewResponse.Content.ReadFromJsonAsync<OnboardingReviewCaseResponse>();
        Assert.NotNull(review);
        Assert.Equal("SUPPLIER", review!.SubjectTypeCode);
        Assert.Equal("SUBMITTED", review.WorkflowStatusCode);
        Assert.Equal(2, review.ChecklistItems.Count);
        Assert.Single(review.Findings);
    }
}
