package main

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

	"wucher/internal/config"
	"wucher/internal/shared/pkg/logger"
)

// writeTestConfig writes a minimal valid JSON config to a temp file and sets
// CONFIG_FILE so that run() can load it.
func writeTestConfig(t *testing.T) {
	t.Helper()
	f := filepath.Join(t.TempDir(), "config.json")
	if err := os.WriteFile(f, []byte("{}"), 0o600); err != nil {
		t.Fatalf("writeTestConfig: %v", err)
	}
	t.Setenv("CONFIG_FILE", f)
}

func TestMain_CallsRun(t *testing.T) {
	origRun := workerRunFn
	t.Cleanup(func() { workerRunFn = origRun })

	runCalled := false
	workerRunFn = func() error {
		runCalled = true
		return nil
	}

	main()

	if !runCalled {
		t.Fatalf("expected worker run function to be called")
	}
}

func TestRun_DefaultsToMailWorker(t *testing.T) {
	origMail := runMailWorkerFn
	origFile := runFileWorkerFn
	t.Cleanup(func() {
		runMailWorkerFn = origMail
		runFileWorkerFn = origFile
	})

	writeTestConfig(t)
	t.Setenv(workerJobEnvKey, "")
	mailCalled := false
	fileCalled := false
	runMailWorkerFn = func(config.AppConfig) error {
		mailCalled = true
		return nil
	}
	runFileWorkerFn = func(config.AppConfig) error {
		fileCalled = true
		return nil
	}

	if err := run(); err != nil {
		t.Fatalf("run: %v", err)
	}
	if !mailCalled {
		t.Fatalf("expected mail worker to be called")
	}
	if fileCalled {
		t.Fatalf("expected file worker not to be called")
	}
}

func TestRun_UsesFileWorkerWhenConfigured(t *testing.T) {
	origMail := runMailWorkerFn
	origFile := runFileWorkerFn
	t.Cleanup(func() {
		runMailWorkerFn = origMail
		runFileWorkerFn = origFile
	})

	writeTestConfig(t)
	t.Setenv(workerJobEnvKey, workerJobFileProcessing)
	mailCalled := false
	fileCalled := false
	runMailWorkerFn = func(config.AppConfig) error {
		mailCalled = true
		return nil
	}
	runFileWorkerFn = func(config.AppConfig) error {
		fileCalled = true
		return nil
	}

	if err := run(); err != nil {
		t.Fatalf("run: %v", err)
	}
	if !fileCalled {
		t.Fatalf("expected file worker to be called")
	}
	if mailCalled {
		t.Fatalf("expected mail worker not to be called")
	}
}

func TestRun_ReturnsErrorOnUnsupportedWorkerJob(t *testing.T) {
	writeTestConfig(t)
	t.Setenv(workerJobEnvKey, "unknown_worker")

	err := run()
	if err == nil || !strings.Contains(err.Error(), "unsupported worker job") {
		t.Fatalf("expected unsupported worker job error, got %v", err)
	}
}

func TestBuildEmailSenderMock(t *testing.T) {
	sender, err := buildEmailSender(context.Background(), config.EmailDeliveryConfig{
		Provider: "mock",
		MockDir:  t.TempDir(),
	}, config.SESConfig{}, config.ResilienceConfig{}, logger.NewDiscard())
	if err != nil {
		t.Fatalf("buildEmailSender: %v", err)
	}
	if sender == nil {
		t.Fatalf("expected sender")
	}
}

func TestBuildEmailSenderUnsupportedProvider(t *testing.T) {
	_, err := buildEmailSender(context.Background(), config.EmailDeliveryConfig{
		Provider: "unknown",
	}, config.SESConfig{}, config.ResilienceConfig{}, logger.NewDiscard())
	if err == nil || !strings.Contains(err.Error(), "unsupported email provider") {
		t.Fatalf("expected unsupported provider error, got %v", err)
	}
}
