using FastEndpoints;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace KArtSell.Modules.ModelOperations.TradeExecution;

[DontRegister]
public class CreateTradeEndpoint : Endpoint<CreateTradeRequest, CreateTradeResponse>
{
    private readonly SubmitTradeHandler _handler;
    private readonly ITradeSql _sql;
    private readonly ILogger<CreateTradeEndpoint> _logger;

    public CreateTradeEndpoint(SubmitTradeHandler handler, ITradeSql sql, ILogger<CreateTradeEndpoint> logger)
    {
        _handler = handler;
        _sql = sql;
        _logger = logger;
    }

    public override void Configure()
    {
        Post("/trades");
        AllowAnonymous();
    }

    public override async Task HandleAsync(CreateTradeRequest req, CancellationToken ct)
    {
        var correlationId = Guid.NewGuid();
        var command = new SubmitTradeCommand
        {
            SellDecisionId = req.SellDecisionId,
            Quantity = req.Quantity,
            LimitPrice = req.LimitPrice,
            CorrelationId = correlationId
        };

        var tradeId = await _handler.HandleAsync(command, ct);
        var trade = await _sql.GetTradeByIdAsync(tradeId, correlationId, ct);

        await Send.ResponseAsync(
            new CreateTradeResponse
            {
                Id = tradeId,
                Status = trade?.Status.ToString() ?? "Unknown",
                SellDecisionId = req.SellDecisionId,
                Quantity = req.Quantity
            },
            StatusCodes.Status202Accepted,
            ct
        );

        _logger.LogInformation("Trade created: {TradeId}", tradeId);
    }
}

[DontRegister]
public class ListTradesEndpoint : Endpoint<EmptyRequest, ListTradesResponse>
{
    private readonly ITradeSql _sql;
    private readonly ILogger<ListTradesEndpoint> _logger;

    public ListTradesEndpoint(ITradeSql sql, ILogger<ListTradesEndpoint> logger)
    {
        _sql = sql;
        _logger = logger;
    }

    public override void Configure()
    {
        Get("/trades");
        AllowAnonymous();
    }

    public override async Task HandleAsync(EmptyRequest req, CancellationToken ct)
    {
        var correlationId = Guid.NewGuid();
        var statusFilter = Query<string>("status");
        var decisionIdFilter = Query<string>("sellDecisionId");

        List<Trade> trades = new();

        if (!string.IsNullOrEmpty(statusFilter) && Enum.TryParse<TradeStatus>(statusFilter, out var status))
        {
            trades = (await _sql.GetTradesByStatusAsync(status, correlationId, ct)).ToList();
        }
        else if (!string.IsNullOrEmpty(decisionIdFilter) && Guid.TryParse(decisionIdFilter, out var decisionId))
        {
            trades = (await _sql.GetTradesByDecisionIdAsync(decisionId, correlationId, ct)).ToList();
        }

        var response = new ListTradesResponse
        {
            Items = trades.Select(t => new TradeDetailResponse
            {
                Id = t.Id,
                Status = t.Status.ToString(),
                SellDecisionId = t.SellDecisionId,
                KisOrderId = t.KisOrderId,
                Quantity = t.Quantity,
                ExecutedQuantity = t.ExecutedQuantity,
                UnitPrice = t.UnitPrice,
                TotalAmount = t.TotalAmount,
                Commission = t.Commission,
                NetProceeds = t.NetProceeds,
                ExecutionTimestamp = t.ExecutionTimestamp,
                SettlementTimestamp = t.SettlementTimestamp
            }),
            Total = trades.Count
        };

        await Send.ResponseAsync(response, StatusCodes.Status200OK, ct);
        _logger.LogInformation("Listed {TradeCount} trades", trades.Count);
    }
}
