using Dapper;
using KArtSell.BuildingBlocks.Data;
using KArtSell.BuildingBlocks.Time;

namespace KArtSell.Modules.ModelOperations.Features.RejectModel;

public sealed class Handler(IDbConnectionFactory connectionFactory, IClock clock)
{
    public async Task<Response> HandleAsync(Request request, Guid rejecterUserId, CancellationToken ct)
    {
        await using var connection = await connectionFactory.OpenAsync(ct);

        // Verify approval exists and is Pending
        var existing = await connection.QuerySingleOrDefaultAsync<(Guid Id, string Status)?>("""
            SELECT id, status FROM model_operations.approval_queue WHERE run_id = @RunId
            """,
            new { request.RunId });

        if (!existing.HasValue)
            throw new InvalidOperationException($"Approval not found for run {request.RunId}");

        if (existing.Value.Status != "Pending")
            throw new InvalidOperationException($"Approval status is {existing.Value.Status}, not Pending");

        // Update approval status (trigger will set rejected_at)
        var now = MarketTime.SeoulDateTime(clock.UtcNow);
        await connection.ExecuteAsync("""
            UPDATE model_operations.approval_queue
            SET
                status = 'Rejected',
                rejection_reason = @RejectionReason,
                rejected_at = @RejectedAt
            WHERE run_id = @RunId
            """,
            new
            {
                request.RunId,
                request.RejectionReason,
                RejectedAt = now
            });

        return new Response(
            existing.Value.Id,
            request.RunId,
            "Rejected",
            now);
    }
}
