// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: webhook_deliveries.sql

package queries

import (
	"context"
	"database/sql"
)

const createWebhookDelivery = `-- name: CreateWebhookDelivery :one

INSERT INTO webhook_deliveries (webhook_id, event_type, payload, status, attempt_count)
VALUES (?, ?, ?, ?, ?)
RETURNING id, webhook_id, event_type, payload, status, http_status_code, response_body, response_headers, error_message, attempt_count, last_attempt_at, next_retry_at, delivered_at, created_at
`

type CreateWebhookDeliveryParams struct {
	WebhookID    int64         `json:"webhook_id"`
	EventType    string        `json:"event_type"`
	Payload      string        `json:"payload"`
	Status       string        `json:"status"`
	AttemptCount sql.NullInt64 `json:"attempt_count"`
}

// Webhook delivery queries
func (q *Queries) CreateWebhookDelivery(ctx context.Context, arg CreateWebhookDeliveryParams) (WebhookDelivery, error) {
	row := q.db.QueryRowContext(ctx, createWebhookDelivery,
		arg.WebhookID,
		arg.EventType,
		arg.Payload,
		arg.Status,
		arg.AttemptCount,
	)
	var i WebhookDelivery
	err := row.Scan(
		&i.ID,
		&i.WebhookID,
		&i.EventType,
		&i.Payload,
		&i.Status,
		&i.HttpStatusCode,
		&i.ResponseBody,
		&i.ResponseHeaders,
		&i.ErrorMessage,
		&i.AttemptCount,
		&i.LastAttemptAt,
		&i.NextRetryAt,
		&i.DeliveredAt,
		&i.CreatedAt,
	)
	return i, err
}

const deleteOldDeliveries = `-- name: DeleteOldDeliveries :exec
DELETE FROM webhook_deliveries 
WHERE created_at < ? AND status IN ('success', 'failed')
`

func (q *Queries) DeleteOldDeliveries(ctx context.Context, createdAt sql.NullTime) error {
	_, err := q.db.ExecContext(ctx, deleteOldDeliveries, createdAt)
	return err
}

const getDeliveryStats = `-- name: GetDeliveryStats :one
SELECT 
    COUNT(*) as total_deliveries,
    COUNT(CASE WHEN status = 'success' THEN 1 END) as successful_deliveries,
    COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed_deliveries,
    COUNT(CASE WHEN status = 'pending' THEN 1 END) as pending_deliveries
FROM webhook_deliveries 
WHERE webhook_id = ? AND created_at >= ?
`

type GetDeliveryStatsParams struct {
	WebhookID int64        `json:"webhook_id"`
	CreatedAt sql.NullTime `json:"created_at"`
}

type GetDeliveryStatsRow struct {
	TotalDeliveries      int64 `json:"total_deliveries"`
	SuccessfulDeliveries int64 `json:"successful_deliveries"`
	FailedDeliveries     int64 `json:"failed_deliveries"`
	PendingDeliveries    int64 `json:"pending_deliveries"`
}

func (q *Queries) GetDeliveryStats(ctx context.Context, arg GetDeliveryStatsParams) (GetDeliveryStatsRow, error) {
	row := q.db.QueryRowContext(ctx, getDeliveryStats, arg.WebhookID, arg.CreatedAt)
	var i GetDeliveryStatsRow
	err := row.Scan(
		&i.TotalDeliveries,
		&i.SuccessfulDeliveries,
		&i.FailedDeliveries,
		&i.PendingDeliveries,
	)
	return i, err
}

const getWebhookDelivery = `-- name: GetWebhookDelivery :one
SELECT id, webhook_id, event_type, payload, status, http_status_code, response_body, response_headers, error_message, attempt_count, last_attempt_at, next_retry_at, delivered_at, created_at FROM webhook_deliveries WHERE id = ?
`

func (q *Queries) GetWebhookDelivery(ctx context.Context, id int64) (WebhookDelivery, error) {
	row := q.db.QueryRowContext(ctx, getWebhookDelivery, id)
	var i WebhookDelivery
	err := row.Scan(
		&i.ID,
		&i.WebhookID,
		&i.EventType,
		&i.Payload,
		&i.Status,
		&i.HttpStatusCode,
		&i.ResponseBody,
		&i.ResponseHeaders,
		&i.ErrorMessage,
		&i.AttemptCount,
		&i.LastAttemptAt,
		&i.NextRetryAt,
		&i.DeliveredAt,
		&i.CreatedAt,
	)
	return i, err
}

const listFailedDeliveriesForRetry = `-- name: ListFailedDeliveriesForRetry :many
SELECT id, webhook_id, event_type, payload, status, http_status_code, response_body, response_headers, error_message, attempt_count, last_attempt_at, next_retry_at, delivered_at, created_at FROM webhook_deliveries 
WHERE status = 'failed' 
    AND next_retry_at IS NOT NULL 
    AND next_retry_at <= CURRENT_TIMESTAMP
ORDER BY next_retry_at ASC
`

func (q *Queries) ListFailedDeliveriesForRetry(ctx context.Context) ([]WebhookDelivery, error) {
	rows, err := q.db.QueryContext(ctx, listFailedDeliveriesForRetry)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WebhookDelivery
	for rows.Next() {
		var i WebhookDelivery
		if err := rows.Scan(
			&i.ID,
			&i.WebhookID,
			&i.EventType,
			&i.Payload,
			&i.Status,
			&i.HttpStatusCode,
			&i.ResponseBody,
			&i.ResponseHeaders,
			&i.ErrorMessage,
			&i.AttemptCount,
			&i.LastAttemptAt,
			&i.NextRetryAt,
			&i.DeliveredAt,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listPendingDeliveries = `-- name: ListPendingDeliveries :many
SELECT id, webhook_id, event_type, payload, status, http_status_code, response_body, response_headers, error_message, attempt_count, last_attempt_at, next_retry_at, delivered_at, created_at FROM webhook_deliveries WHERE status = 'pending' ORDER BY created_at ASC
`

func (q *Queries) ListPendingDeliveries(ctx context.Context) ([]WebhookDelivery, error) {
	rows, err := q.db.QueryContext(ctx, listPendingDeliveries)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WebhookDelivery
	for rows.Next() {
		var i WebhookDelivery
		if err := rows.Scan(
			&i.ID,
			&i.WebhookID,
			&i.EventType,
			&i.Payload,
			&i.Status,
			&i.HttpStatusCode,
			&i.ResponseBody,
			&i.ResponseHeaders,
			&i.ErrorMessage,
			&i.AttemptCount,
			&i.LastAttemptAt,
			&i.NextRetryAt,
			&i.DeliveredAt,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listWebhookDeliveries = `-- name: ListWebhookDeliveries :many
SELECT id, webhook_id, event_type, payload, status, http_status_code, response_body, response_headers, error_message, attempt_count, last_attempt_at, next_retry_at, delivered_at, created_at FROM webhook_deliveries ORDER BY created_at DESC LIMIT ?
`

func (q *Queries) ListWebhookDeliveries(ctx context.Context, limit int64) ([]WebhookDelivery, error) {
	rows, err := q.db.QueryContext(ctx, listWebhookDeliveries, limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WebhookDelivery
	for rows.Next() {
		var i WebhookDelivery
		if err := rows.Scan(
			&i.ID,
			&i.WebhookID,
			&i.EventType,
			&i.Payload,
			&i.Status,
			&i.HttpStatusCode,
			&i.ResponseBody,
			&i.ResponseHeaders,
			&i.ErrorMessage,
			&i.AttemptCount,
			&i.LastAttemptAt,
			&i.NextRetryAt,
			&i.DeliveredAt,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listWebhookDeliveriesByWebhook = `-- name: ListWebhookDeliveriesByWebhook :many
SELECT id, webhook_id, event_type, payload, status, http_status_code, response_body, response_headers, error_message, attempt_count, last_attempt_at, next_retry_at, delivered_at, created_at FROM webhook_deliveries WHERE webhook_id = ? ORDER BY created_at DESC LIMIT ?
`

type ListWebhookDeliveriesByWebhookParams struct {
	WebhookID int64 `json:"webhook_id"`
	Limit     int64 `json:"limit"`
}

func (q *Queries) ListWebhookDeliveriesByWebhook(ctx context.Context, arg ListWebhookDeliveriesByWebhookParams) ([]WebhookDelivery, error) {
	rows, err := q.db.QueryContext(ctx, listWebhookDeliveriesByWebhook, arg.WebhookID, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WebhookDelivery
	for rows.Next() {
		var i WebhookDelivery
		if err := rows.Scan(
			&i.ID,
			&i.WebhookID,
			&i.EventType,
			&i.Payload,
			&i.Status,
			&i.HttpStatusCode,
			&i.ResponseBody,
			&i.ResponseHeaders,
			&i.ErrorMessage,
			&i.AttemptCount,
			&i.LastAttemptAt,
			&i.NextRetryAt,
			&i.DeliveredAt,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const markDeliveryAsFailed = `-- name: MarkDeliveryAsFailed :exec
UPDATE webhook_deliveries 
SET status = 'failed',
    error_message = ?,
    last_attempt_at = CURRENT_TIMESTAMP
WHERE id = ?
`

type MarkDeliveryAsFailedParams struct {
	ErrorMessage sql.NullString `json:"error_message"`
	ID           int64          `json:"id"`
}

func (q *Queries) MarkDeliveryAsFailed(ctx context.Context, arg MarkDeliveryAsFailedParams) error {
	_, err := q.db.ExecContext(ctx, markDeliveryAsFailed, arg.ErrorMessage, arg.ID)
	return err
}

const markDeliveryAsSuccess = `-- name: MarkDeliveryAsSuccess :exec
UPDATE webhook_deliveries 
SET status = 'success',
    http_status_code = ?,
    response_body = ?,
    response_headers = ?,
    delivered_at = CURRENT_TIMESTAMP,
    last_attempt_at = CURRENT_TIMESTAMP
WHERE id = ?
`

type MarkDeliveryAsSuccessParams struct {
	HttpStatusCode  sql.NullInt64  `json:"http_status_code"`
	ResponseBody    sql.NullString `json:"response_body"`
	ResponseHeaders sql.NullString `json:"response_headers"`
	ID              int64          `json:"id"`
}

func (q *Queries) MarkDeliveryAsSuccess(ctx context.Context, arg MarkDeliveryAsSuccessParams) error {
	_, err := q.db.ExecContext(ctx, markDeliveryAsSuccess,
		arg.HttpStatusCode,
		arg.ResponseBody,
		arg.ResponseHeaders,
		arg.ID,
	)
	return err
}

const updateDeliveryForRetry = `-- name: UpdateDeliveryForRetry :exec
UPDATE webhook_deliveries 
SET attempt_count = attempt_count + 1,
    last_attempt_at = CURRENT_TIMESTAMP,
    next_retry_at = ?,
    status = 'failed',
    http_status_code = ?,
    response_body = ?,
    response_headers = ?,
    error_message = ?
WHERE id = ?
`

type UpdateDeliveryForRetryParams struct {
	NextRetryAt     sql.NullTime   `json:"next_retry_at"`
	HttpStatusCode  sql.NullInt64  `json:"http_status_code"`
	ResponseBody    sql.NullString `json:"response_body"`
	ResponseHeaders sql.NullString `json:"response_headers"`
	ErrorMessage    sql.NullString `json:"error_message"`
	ID              int64          `json:"id"`
}

func (q *Queries) UpdateDeliveryForRetry(ctx context.Context, arg UpdateDeliveryForRetryParams) error {
	_, err := q.db.ExecContext(ctx, updateDeliveryForRetry,
		arg.NextRetryAt,
		arg.HttpStatusCode,
		arg.ResponseBody,
		arg.ResponseHeaders,
		arg.ErrorMessage,
		arg.ID,
	)
	return err
}

const updateDeliveryStatus = `-- name: UpdateDeliveryStatus :exec
UPDATE webhook_deliveries 
SET status = ?, 
    http_status_code = ?, 
    response_body = ?, 
    response_headers = ?, 
    error_message = ?,
    last_attempt_at = CURRENT_TIMESTAMP,
    delivered_at = CASE WHEN ? = 'success' THEN CURRENT_TIMESTAMP ELSE delivered_at END
WHERE id = ?
`

type UpdateDeliveryStatusParams struct {
	Status          string         `json:"status"`
	HttpStatusCode  sql.NullInt64  `json:"http_status_code"`
	ResponseBody    sql.NullString `json:"response_body"`
	ResponseHeaders sql.NullString `json:"response_headers"`
	ErrorMessage    sql.NullString `json:"error_message"`
	Column6         interface{}    `json:"column_6"`
	ID              int64          `json:"id"`
}

func (q *Queries) UpdateDeliveryStatus(ctx context.Context, arg UpdateDeliveryStatusParams) error {
	_, err := q.db.ExecContext(ctx, updateDeliveryStatus,
		arg.Status,
		arg.HttpStatusCode,
		arg.ResponseBody,
		arg.ResponseHeaders,
		arg.ErrorMessage,
		arg.Column6,
		arg.ID,
	)
	return err
}
