using Dapper;
using Npgsql;

namespace Kbx.Shared.Integrations;

public sealed class KbxIntegrationAttemptRepository(NpgsqlDataSource dataSource)
{
    public async Task<Guid> StartAsync(KbxIntegrationMessage message, int attemptNo, CancellationToken ct)
    {
        const string sql = """
        insert into kbx.integration_attempts(id, tenant_id, integration_id, message_id, aggregate_type, aggregate_id,
          aggregate_version, attempt_no, state, correlation_id, started_at)
        values (@Id,@TenantId,@IntegrationId,@MessageId,@AggregateType,@AggregateId,@AggregateVersion,@AttemptNo,'delivering',@CorrelationId,now())
        on conflict (tenant_id,integration_id,message_id,attempt_no) do update set correlation_id=excluded.correlation_id
        returning id;
        """;
        await using var connection = await dataSource.OpenConnectionAsync(ct);
        return await connection.ExecuteScalarAsync<Guid>(new CommandDefinition(sql, new {
            Id=Guid.NewGuid(), message.TenantId, message.IntegrationId, message.MessageId, message.AggregateType,
            message.AggregateId, message.AggregateVersion, AttemptNo=attemptNo, message.CorrelationId
        }, cancellationToken:ct));
    }

    public async Task CompleteAsync(Guid id, KbxIntegrationAttemptResult result, string state, DateTimeOffset? nextRetryAt, CancellationToken ct)
    {
        const string sql = """
        update kbx.integration_attempts
           set state=@State, completed_at=now(), failure_kind=@FailureKind, failure_code=@Code, detail=@Detail,
               http_status=@HttpStatus, external_reference=@ExternalReference, next_retry_at=@NextRetryAt
         where id=@Id;
        """;
        await using var connection=await dataSource.OpenConnectionAsync(ct);
        await connection.ExecuteAsync(new CommandDefinition(sql,new { Id=id, State=state, FailureKind=result.FailureKind?.ToString().ToLowerInvariant(), result.Code, result.Detail, result.HttpStatus, result.ExternalReference, NextRetryAt=nextRetryAt },cancellationToken:ct));
    }
}
