package jobs

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

	"github.com/hibiken/asynq"
	"github.com/rs/zerolog/log"

	"github.com/treytartt/honeydue-api/internal/services"
	"github.com/treytartt/honeydue-api/internal/worker"
)

// EmailJobHandler handles email-related background jobs
type EmailJobHandler struct {
	emailService *services.EmailService
}

// NewEmailJobHandler creates a new email job handler
func NewEmailJobHandler(emailService *services.EmailService) *EmailJobHandler {
	return &EmailJobHandler{
		emailService: emailService,
	}
}

// RegisterHandlers registers all email job handlers with the mux
func (h *EmailJobHandler) RegisterHandlers(mux *asynq.ServeMux) {
	mux.HandleFunc(worker.TypeWelcomeEmail, h.HandleWelcomeEmail)
	mux.HandleFunc(worker.TypeVerificationEmail, h.HandleVerificationEmail)
	mux.HandleFunc(worker.TypePasswordResetEmail, h.HandlePasswordResetEmail)
	mux.HandleFunc(worker.TypePasswordChangedEmail, h.HandlePasswordChangedEmail)
}

// HandleWelcomeEmail handles the welcome email task
func (h *EmailJobHandler) HandleWelcomeEmail(ctx context.Context, t *asynq.Task) error {
	var p worker.WelcomeEmailPayload
	if err := json.Unmarshal(t.Payload(), &p); err != nil {
		return fmt.Errorf("failed to unmarshal payload: %w", err)
	}

	log.Info().
		Str("to", p.To).
		Str("type", "welcome").
		Msg("Processing email job")

	if err := h.emailService.SendWelcomeEmail(p.To, p.FirstName, p.ConfirmationCode); err != nil {
		log.Error().Err(err).Str("to", p.To).Msg("Failed to send welcome email")
		return err
	}

	log.Info().Str("to", p.To).Msg("Welcome email sent successfully")
	return nil
}

// HandleVerificationEmail handles the verification email task
func (h *EmailJobHandler) HandleVerificationEmail(ctx context.Context, t *asynq.Task) error {
	var p worker.VerificationEmailPayload
	if err := json.Unmarshal(t.Payload(), &p); err != nil {
		return fmt.Errorf("failed to unmarshal payload: %w", err)
	}

	log.Info().
		Str("to", p.To).
		Str("type", "verification").
		Msg("Processing email job")

	if err := h.emailService.SendVerificationEmail(p.To, p.FirstName, p.Code); err != nil {
		log.Error().Err(err).Str("to", p.To).Msg("Failed to send verification email")
		return err
	}

	log.Info().Str("to", p.To).Msg("Verification email sent successfully")
	return nil
}

// HandlePasswordResetEmail handles the password reset email task
func (h *EmailJobHandler) HandlePasswordResetEmail(ctx context.Context, t *asynq.Task) error {
	var p worker.PasswordResetEmailPayload
	if err := json.Unmarshal(t.Payload(), &p); err != nil {
		return fmt.Errorf("failed to unmarshal payload: %w", err)
	}

	log.Info().
		Str("to", p.To).
		Str("type", "password_reset").
		Msg("Processing email job")

	if err := h.emailService.SendPasswordResetEmail(p.To, p.FirstName, p.Code); err != nil {
		log.Error().Err(err).Str("to", p.To).Msg("Failed to send password reset email")
		return err
	}

	log.Info().Str("to", p.To).Msg("Password reset email sent successfully")
	return nil
}

// HandlePasswordChangedEmail handles the password changed confirmation email task
func (h *EmailJobHandler) HandlePasswordChangedEmail(ctx context.Context, t *asynq.Task) error {
	var p worker.EmailPayload
	if err := json.Unmarshal(t.Payload(), &p); err != nil {
		return fmt.Errorf("failed to unmarshal payload: %w", err)
	}

	log.Info().
		Str("to", p.To).
		Str("type", "password_changed").
		Msg("Processing email job")

	if err := h.emailService.SendPasswordChangedEmail(p.To, p.FirstName); err != nil {
		log.Error().Err(err).Str("to", p.To).Msg("Failed to send password changed email")
		return err
	}

	log.Info().Str("to", p.To).Msg("Password changed email sent successfully")
	return nil
}
