package jobs

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/hibiken/asynq"
)

const (
	// Job types
	TypeSendOTPEmail = "email:send_otp"
)

// SendOTPEmailPayload holds the data for sending OTP email
type SendOTPEmailPayload struct {
	Email string `json:"email"`
	OTP   string `json:"otp"`
}

// NewSendOTPEmailTask creates a new task for sending OTP email
func NewSendOTPEmailTask(email, otp string) (*asynq.Task, error) {
	payload := SendOTPEmailPayload{
		Email: email,
		OTP:   otp,
	}
	
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal payload: %w", err)
	}
	
	// Set task options: retry up to 3 times with exponential backoff
	opts := []asynq.Option{
		asynq.MaxRetry(3),
		asynq.Queue("emails"),
		asynq.Timeout(60 * time.Second), // 60 seconds timeout for email sending (increased for slow SMTP servers)
	}
	
	return asynq.NewTask(TypeSendOTPEmail, payloadBytes, opts...), nil
}

// ProcessSendOTPEmail processes the send OTP email task
func ProcessSendOTPEmail(emailService EmailService) asynq.HandlerFunc {
	return func(ctx context.Context, t *asynq.Task) error {
		var payload SendOTPEmailPayload
		if err := json.Unmarshal(t.Payload(), &payload); err != nil {
			return fmt.Errorf("failed to unmarshal payload: %w", asynq.SkipRetry)
		}
		
		log.Printf("Processing email job: sending OTP to %s", payload.Email)
		
		err := emailService.SendOTP(payload.Email, payload.OTP)
		if err != nil {
			log.Printf("Failed to send OTP email to %s: %v", payload.Email, err)
			return fmt.Errorf("failed to send email: %w", err)
		}
		
		log.Printf("Successfully sent OTP email to %s", payload.Email)
		return nil
	}
}

// EmailService interface for sending emails
type EmailService interface {
	SendOTP(email, otp string) error
}

