using System.Net;
using System.Net.Http.Json;
using CashLineERP.Application.IslamicFinance.ProductProfiles;
using CashLineERP.Contracts.IslamicFinance;
using CashLineERP.Infrastructure.Persistence;
using CashLineERP.Infrastructure.Persistence.Repositories.IslamicFinance;
using Microsoft.Extensions.DependencyInjection;

namespace CashLineERP.Api.Tests;

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

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

    [Fact]
    public async Task Contract_Template_Endpoints_Support_Create_Submit_Approve_Activate_And_Reads()
    {
        await _client.AuthenticateAsInternalAsync();
        var productId = SeedActiveProduct();

        var createResponse = await _client.PostAsJsonAsync("/api/v1/islamic-finance/contract-templates", new CreateIslamicFinanceContractTemplateRequest
        {
            ProductProfileId = productId,
            TemplateCode = $"MUR-TPL-{Guid.NewGuid():N}"[..14].ToUpperInvariant(),
            TemplateName = "Murabaha English Contract",
            LanguageCode = "EN"
        });

        Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);
        var created = await createResponse.Content.ReadFromJsonAsync<IslamicFinanceContractTemplateResponse>();
        Assert.NotNull(created);
        Assert.Equal("DRAFT", created!.StatusCode);

        var submitResponse = await _client.PostAsync($"/api/v1/islamic-finance/contract-templates/{created.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitResponse.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveResponse = await _client.PostAsync($"/api/v1/islamic-finance/contract-templates/{created.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveResponse.StatusCode);

        var activateResponse = await _client.PostAsync($"/api/v1/islamic-finance/contract-templates/{created.Id}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);
        var activated = await activateResponse.Content.ReadFromJsonAsync<IslamicFinanceContractTemplateResponse>();
        Assert.NotNull(activated);
        Assert.True(activated!.IsActive);

        var detailResponse = await _client.GetAsync($"/api/v1/islamic-finance/contract-templates/{created.Id}");
        Assert.Equal(HttpStatusCode.OK, detailResponse.StatusCode);

        var listResponse = await _client.GetAsync($"/api/v1/islamic-finance/contract-templates?activeOnly=true&productProfileId={productId}&languageCode=EN");
        Assert.Equal(HttpStatusCode.OK, listResponse.StatusCode);
        var list = await listResponse.Content.ReadFromJsonAsync<IslamicFinanceContractTemplateResponse[]>();
        Assert.NotNull(list);
        Assert.Single(list!);
    }

    private long SeedActiveProduct()
    {
        using var scope = _factory.Services.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<CashLineErpDbContext>();
        var productService = new IslamicFinanceProductService(new IslamicFinanceProductRepository(dbContext));

        var created = productService.CreateProductProfile(new CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "MURABAHA",
            ProductCode = $"MUR-TPLH-{Guid.NewGuid():N}"[..14].ToUpperInvariant(),
            ProductName = "Murabaha Contract HTTP Product",
            RequiresShariahReview = true,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = false
        });

        productService.SubmitProductProfile(created.Id, 3);
        productService.ApproveProductProfile(created.Id, 4);
        return productService.ActivateProductProfile(created.Id, 4).Id;
    }
}
