using FastEndpoints;
using Microsoft.AspNetCore.Http;
using System.Text.Json;
using KArtSell.Modules.SignalEngine.Application;

namespace KArtSell.Modules.SignalEngine.Features.GenerateSellDecision;

public sealed class Endpoint(ISellDecisionService service) : Endpoint<Request, Response>
{
    public override void Configure()
    {
        Post("/internal/v1/signal-decisions");
        Roles("Quant", "System");
        Description(x => x.WithTags("SignalEngine"));
    }

    public override async Task HandleAsync(Request req, CancellationToken ct)
    {
        var idempotencyKey = HttpContext.Request.Headers["Idempotency-Key"].ToString();
        if (string.IsNullOrWhiteSpace(idempotencyKey) || idempotencyKey.Length > 128)
        {
            HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
            await HttpContext.Response.WriteAsJsonAsync(new
            {
                type = "https://kartsell.local/problems/idempotency-key",
                title = "Idempotency-Key is required.",
                status = 400
            }, ct);
            return;
        }

        var result = await service.GenerateAsync(
            new GenerateSellDecisionCommand(
                req.PositionLotId,
                req.AsOf,
                idempotencyKey,
                HttpContext.TraceIdentifier),
            ct);

        if (result is null)
        {
            HttpContext.Response.StatusCode = StatusCodes.Status409Conflict;
            await HttpContext.Response.WriteAsJsonAsync(new
            {
                type = "https://kartsell.local/problems/approved-evidence-not-found",
                title = "Approved point-in-time evidence is not available.",
                status = 409
            }, ct);
            return;
        }

        await Send.OkAsync(new Response(
            result.DecisionId,
            result.Action,
            result.SellRatioOfLot,
            result.TargetSecurityPortfolioWeightAfter,
            result.PolicyId,
            result.ReasonCode,
            result.EvidenceId,
            result.DatasetId,
            result.ModelVersion,
            result.ConfigVersion,
            result.CodeSha,
            result.DecisionContractVersion,
            result.PolicyTraceSchemaVersion,
            result.ReentryEligible,
            result.PolicyTrace,
            result.CreatedAt,
            result.Replayed), ct);
    }
}
