package workers

import (
	"bytes"
	"context"
	"fmt"
	"html/template"
	"os"
	"path/filepath"

	"veza-backend-api/internal/email"

	"go.uber.org/zap"
)

// EmailJob représente un job d'envoi d'email
type EmailJob struct {
	To       string
	Subject  string
	Body     string
	Template string                 // Nom du template (ex: "password_reset")
	Data     map[string]interface{} // Données pour le template
}

// NewEmailJob crée un nouveau job d'email
func NewEmailJob(to, subject, body string) *EmailJob {
	return &EmailJob{
		To:      to,
		Subject: subject,
		Body:    body,
		Data:    make(map[string]interface{}),
	}
}

// NewEmailJobWithTemplate crée un job d'email avec template
func NewEmailJobWithTemplate(to, subject, templateName string, data map[string]interface{}) *EmailJob {
	return &EmailJob{
		To:       to,
		Subject:  subject,
		Template: templateName,
		Data:     data,
	}
}

// Execute exécute le job d'email
func (j *EmailJob) Execute(ctx context.Context, sender email.EmailSender, logger *zap.Logger) error {
	// Si un template est spécifié, le rendre
	body := j.Body
	if j.Template != "" {
		rendered, err := j.renderTemplate(j.Template, j.Data)
		if err != nil {
			logger.Error("Failed to render email template",
				zap.String("template", j.Template),
				zap.Error(err),
			)
			return fmt.Errorf("failed to render template: %w", err)
		}
		body = rendered
	}

	// Envoyer l'email
	if err := sender.Send(j.To, j.Subject, body); err != nil {
		logger.Error("Failed to send email",
			zap.String("to", j.To),
			zap.String("subject", j.Subject),
			zap.Error(err),
		)
		return fmt.Errorf("failed to send email: %w", err)
	}

	logger.Info("Email job executed successfully",
		zap.String("to", j.To),
		zap.String("subject", j.Subject),
		zap.String("template", j.Template),
	)

	return nil
}

// renderTemplate rend un template email
func (j *EmailJob) renderTemplate(templateName string, data map[string]interface{}) (string, error) {
	// Chercher le template dans templates/email/
	templateDir := os.Getenv("EMAIL_TEMPLATE_DIR")
	if templateDir == "" {
		templateDir = "templates/email"
	}

	templatePath := filepath.Join(templateDir, templateName+".html")

	// Lire le fichier template
	tmplContent, err := os.ReadFile(templatePath)
	if err != nil {
		return "", fmt.Errorf("failed to read template file %s: %w", templatePath, err)
	}

	// Parser le template
	tmpl, err := template.New(templateName).Parse(string(tmplContent))
	if err != nil {
		return "", fmt.Errorf("failed to parse template: %w", err)
	}

	// Rendre le template avec les données
	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, data); err != nil {
		return "", fmt.Errorf("failed to execute template: %w", err)
	}

	return buf.String(), nil
}
