using System.Net;
using System.Net.Http.Json;
using CashLineERP.Contracts.Finance;

namespace CashLineERP.Api.Tests;

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

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

    [Fact]
    public async Task Wallet_Rule_Endpoints_Support_Create_Submit_Approve_Activate_Evaluate_And_Reads()
    {
        await _client.AuthenticateAsFinanceMakerAsync();

        var createResponse = await _client.PostAsJsonAsync("/api/v1/finance/wallet-rules", new CreateWalletRuleRequest(
            RuleName: "HTTP wallet rule",
            BranchId: 1,
            PartyTypeCode: "CUSTOMER",
            TransactionTypeCode: "COLLECTION",
            WalletSchemeCode: "MOBILE_WALLET",
            IntegrationProviderCode: "PAYMOB",
            CurrencyCode: "EGP",
            MinimumAmount: 10m,
            MaximumAmount: 3000m,
            SettlementLeadDays: 1,
            FeePercent: 1.25m,
            FlatFeeAmount: 1m,
            Priority: 7,
            EffectiveFromDate: new DateOnly(2026, 4, 5),
            EffectiveToDate: null,
            Notes: "HTTP wallet baseline"));
        Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);

        var createdRule = await createResponse.Content.ReadFromJsonAsync<WalletRuleResponse>();
        Assert.NotNull(createdRule);
        Assert.Equal("DRAFT", createdRule!.StatusCode);

        var submitResponse = await _client.PostAsync($"/api/v1/finance/wallet-rules/{createdRule.WalletRuleId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitResponse.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveResponse = await _client.PostAsync($"/api/v1/finance/wallet-rules/{createdRule.WalletRuleId}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveResponse.StatusCode);

        var activateResponse = await _client.PostAsync($"/api/v1/finance/wallet-rules/{createdRule.WalletRuleId}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);
        var activatedRule = await activateResponse.Content.ReadFromJsonAsync<WalletRuleResponse>();
        Assert.NotNull(activatedRule);
        Assert.True(activatedRule!.IsActive);

        var evaluateResponse = await _client.PostAsJsonAsync("/api/v1/finance/wallet-rules/evaluate", new WalletRuleEvaluationRequest(
            BranchId: 1,
            PartyTypeCode: "CUSTOMER",
            TransactionTypeCode: "COLLECTION",
            WalletSchemeCode: "MOBILE_WALLET",
            CurrencyCode: "EGP",
            RequestedAmount: 200m,
            EvaluationDate: new DateOnly(2026, 4, 6)));
        Assert.Equal(HttpStatusCode.OK, evaluateResponse.StatusCode);
        var evaluation = await evaluateResponse.Content.ReadFromJsonAsync<WalletRuleEvaluationResponse>();
        Assert.NotNull(evaluation);
        Assert.Equal(createdRule.WalletRuleId, evaluation!.RecommendedWalletRuleId);
        Assert.Single(evaluation.Lines);

        var detailResponse = await _client.GetAsync($"/api/v1/finance/wallet-rules/{createdRule.WalletRuleId}");
        Assert.Equal(HttpStatusCode.OK, detailResponse.StatusCode);

        var listResponse = await _client.GetAsync("/api/v1/finance/wallet-rules?activeOnly=true&integrationProviderCode=PAYMOB&transactionTypeCode=COLLECTION");
        Assert.Equal(HttpStatusCode.OK, listResponse.StatusCode);
        var listedRules = await listResponse.Content.ReadFromJsonAsync<WalletRuleResponse[]>();
        Assert.NotNull(listedRules);
        Assert.Single(listedRules!);
    }
}
