package services

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"log"

	amqp "github.com/rabbitmq/amqp091-go"
)

type EmailService struct {
	db                 *sql.DB
	credentialsService *CredentialsService
}

func NewEmailService(db *sql.DB, cs *CredentialsService) *EmailService {
	return &EmailService{
		db:                 db,
		credentialsService: cs,
	} // Ensure return pointer matches
}

type EmailJob struct {
	To        string                 `json:"to"`
	Template  string                 `json:"template"` // slug
	Variables map[string]interface{} `json:"variables"`
}

// SendTemplateEmail queues an email via RabbitMQ
func (s *EmailService) SendTemplateEmail(ctx context.Context, to, templateSlug string, variables map[string]interface{}) error {
	// 1. Get AMQP URL from email_settings
	var amqpURL sql.NullString
	err := s.db.QueryRowContext(ctx, "SELECT amqp_url FROM email_settings LIMIT 1").Scan(&amqpURL)
	if err != nil && err != sql.ErrNoRows {
		log.Printf("[EmailService] Failed to fetch AMQP URL: %v", err)
	}

	url := ""
	if amqpURL.Valid {
		url = amqpURL.String
	}

	if url == "" {
		// Log but don't error hard if just testing, but for "system" we need IT.
		// Return error so caller knows.
		return fmt.Errorf("AMQP URL not configured in email_settings")
	}

	// 2. Connect & Publish
	conn, err := amqp.Dial(url)
	if err != nil {
		return fmt.Errorf("failed to connect to RabbitMQ: %w", err)
	}
	defer conn.Close()

	ch, err := conn.Channel()
	if err != nil {
		return fmt.Errorf("failed to open channel: %w", err)
	}
	defer ch.Close()

	q, err := ch.QueueDeclare(
		"mail_queue", // name
		true,         // durable
		false,        // delete when unused
		false,        // exclusive
		false,        // no-wait
		nil,          // arguments
	)
	if err != nil {
		return fmt.Errorf("failed to declare queue: %w", err)
	}

	job := EmailJob{To: to, Template: templateSlug, Variables: variables}
	body, _ := json.Marshal(job)

	err = ch.PublishWithContext(ctx,
		"",     // exchange
		q.Name, // routing key
		false,  // mandatory
		false,  // immediate
		amqp.Publishing{
			ContentType: "application/json",
			Body:        body,
		})
	if err != nil {
		return fmt.Errorf("failed to publish message: %w", err)
	}

	log.Printf("[EmailService] Queued email to %s (Template: %s)", to, templateSlug)
	return nil
}
