package workers

import (
	"context"
	"os"
	"path/filepath"
	"strings"
	"testing"

	// "veza-backend-api/internal/email" // Removed unused import

	"go.uber.org/zap"
)

// mockEmailSender est un mock pour EmailSender
type mockEmailSender struct {
	sentEmails []emailSent
}

type emailSent struct {
	to      string
	subject string
	body    string
}

func (m *mockEmailSender) Send(to, subject, body string) error {
	m.sentEmails = append(m.sentEmails, emailSent{to, subject, body})
	return nil
}

func (m *mockEmailSender) SendTemplate(to, template string, data map[string]interface{}) error {
	return nil
}

func TestNewEmailJob(t *testing.T) {
	job := NewEmailJob("test@example.com", "Test Subject", "Test Body")

	if job.To != "test@example.com" {
		t.Errorf("Expected To to be 'test@example.com', got %s", job.To)
	}
	if job.Subject != "Test Subject" {
		t.Errorf("Expected Subject to be 'Test Subject', got %s", job.Subject)
	}
	if job.Body != "Test Body" {
		t.Errorf("Expected Body to be 'Test Body', got %s", job.Body)
	}
}

func TestNewEmailJobWithTemplate(t *testing.T) {
	data := map[string]interface{}{
		"Username": "testuser",
		"ResetURL": "http://localhost/reset?token=abc123",
	}

	job := NewEmailJobWithTemplate("test@example.com", "Reset Password", "password_reset", data)

	if job.To != "test@example.com" {
		t.Errorf("Expected To to be 'test@example.com', got %s", job.To)
	}
	if job.Template != "password_reset" {
		t.Errorf("Expected Template to be 'password_reset', got %s", job.Template)
	}
	if len(job.Data) != 2 {
		t.Errorf("Expected Data to have 2 items, got %d", len(job.Data))
	}
}

func TestEmailJob_Execute(t *testing.T) {
	logger, _ := zap.NewDevelopment()
	defer logger.Sync()

	mockSender := &mockEmailSender{}
	job := NewEmailJob("test@example.com", "Test Subject", "Test Body")

	ctx := context.Background()
	err := job.Execute(ctx, mockSender, logger)
	if err != nil {
		t.Fatalf("Execute failed: %v", err)
	}

	if len(mockSender.sentEmails) != 1 {
		t.Fatalf("Expected 1 email to be sent, got %d", len(mockSender.sentEmails))
	}

	sent := mockSender.sentEmails[0]
	if sent.to != "test@example.com" {
		t.Errorf("Expected to be 'test@example.com', got %s", sent.to)
	}
	if sent.subject != "Test Subject" {
		t.Errorf("Expected subject to be 'Test Subject', got %s", sent.subject)
	}
}

func TestEmailJob_ExecuteWithTemplate(t *testing.T) {
	logger, _ := zap.NewDevelopment()
	defer logger.Sync()

	// Créer un template de test temporaire
	tempDir := t.TempDir()
	templateDir := filepath.Join(tempDir, "templates", "email")
	os.MkdirAll(templateDir, 0755)

	templatePath := filepath.Join(templateDir, "test_template.html")
	templateContent := `<html><body>Hello {{.Name}}, URL: {{.URL}}</body></html>`
	os.WriteFile(templatePath, []byte(templateContent), 0644)

	// Définir EMAIL_TEMPLATE_DIR pour le test
	oldDir := os.Getenv("EMAIL_TEMPLATE_DIR")
	os.Setenv("EMAIL_TEMPLATE_DIR", templateDir)
	defer os.Setenv("EMAIL_TEMPLATE_DIR", oldDir)

	mockSender := &mockEmailSender{}
	data := map[string]interface{}{
		"Name": "TestUser",
		"URL":  "http://example.com",
	}

	job := NewEmailJobWithTemplate("test@example.com", "Test Subject", "test_template", data)

	ctx := context.Background()
	err := job.Execute(ctx, mockSender, logger)
	if err != nil {
		t.Fatalf("Execute failed: %v", err)
	}

	if len(mockSender.sentEmails) != 1 {
		t.Fatalf("Expected 1 email to be sent, got %d", len(mockSender.sentEmails))
	}

	sent := mockSender.sentEmails[0]
	if sent.body == "" {
		t.Error("Expected body to be rendered from template")
	}
	// Vérifier que le template a été rendu
	if !strings.Contains(sent.body, "TestUser") {
		t.Errorf("Expected body to contain 'TestUser', got: %s", sent.body)
	}
}
