package mail

import (
	"context"
	"errors"
	"time"

	"github.com/jackc/pgx/v5"
)

var ErrInvalidOutboxStatus = errors.New("invalid outbox status")

func (s *Service) SendOutboxNow(ctx context.Context, userID, outboxID string) (string, error) {
	var status string
	err := s.db.QueryRow(ctx, `
		UPDATE outbox SET status = 'queued', scheduled_at = NULL, updated_at = NOW()
		WHERE id = $1 AND user_id = $2 AND status = 'scheduled'
		RETURNING status
	`, outboxID, userID).Scan(&status)
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return "", s.outboxActionError(ctx, userID, outboxID)
		}
		return "", err
	}
	return status, nil
}

func (s *Service) RescheduleOutbox(ctx context.Context, userID, outboxID string, scheduledAt time.Time) (string, error) {
	var status string
	err := s.db.QueryRow(ctx, `
		UPDATE outbox SET status = 'scheduled', scheduled_at = $3, updated_at = NOW()
		WHERE id = $1 AND user_id = $2 AND status IN ('scheduled', 'queued')
		RETURNING status
	`, outboxID, userID, scheduledAt).Scan(&status)
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return "", s.outboxActionError(ctx, userID, outboxID)
		}
		return "", err
	}
	return status, nil
}

func (s *Service) CancelScheduledOutbox(ctx context.Context, userID, outboxID string) (string, error) {
	var status string
	err := s.db.QueryRow(ctx, `
		UPDATE outbox SET status = 'cancelled', scheduled_at = NULL, updated_at = NOW()
		WHERE id = $1 AND user_id = $2 AND status = 'scheduled'
		RETURNING status
	`, outboxID, userID).Scan(&status)
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return "", s.outboxActionError(ctx, userID, outboxID)
		}
		return "", err
	}
	return status, nil
}

func (s *Service) outboxActionError(ctx context.Context, userID, outboxID string) error {
	var status string
	err := s.db.QueryRow(ctx, `
		SELECT status FROM outbox WHERE id = $1 AND user_id = $2
	`, outboxID, userID).Scan(&status)
	if errors.Is(err, pgx.ErrNoRows) {
		return ErrNotFound
	}
	if err != nil {
		return err
	}
	return ErrInvalidOutboxStatus
}
