package config

import (
	"os"
	"testing"
	"time"
)

func TestLoadDefaults(t *testing.T) {
	// Clear any environment variables that might interfere
	envVars := []string{
		"APP_NAME", "PORT", "DATABASE_URL", "DB_MAX_OPEN_CONNS",
		"DB_MAX_IDLE_CONNS", "DB_CONN_MAX_IDLE", "MERCADOPAGO_BASE_URL",
		"MARKETPLACE_COMMISSION", "JWT_SECRET", "JWT_EXPIRES_IN",
		"PASSWORD_PEPPER", "CORS_ORIGINS",
	}
	origEnvs := make(map[string]string)
	for _, key := range envVars {
		origEnvs[key] = os.Getenv(key)
		os.Unsetenv(key)
	}
	defer func() {
		for key, val := range origEnvs {
			if val != "" {
				os.Setenv(key, val)
			}
		}
	}()

	cfg := Load()

	if cfg.AppName != "saveinmed-performance-core" {
		t.Errorf("expected AppName 'saveinmed-performance-core', got '%s'", cfg.AppName)
	}
	if cfg.Port != "8214" {
		t.Errorf("expected Port '8214', got '%s'", cfg.Port)
	}
	if cfg.MaxOpenConns != 15 {
		t.Errorf("expected MaxOpenConns 15, got %d", cfg.MaxOpenConns)
	}
	if cfg.MaxIdleConns != 5 {
		t.Errorf("expected MaxIdleConns 5, got %d", cfg.MaxIdleConns)
	}
	if cfg.ConnMaxIdle != 5*time.Minute {
		t.Errorf("expected ConnMaxIdle 5m, got %v", cfg.ConnMaxIdle)
	}
	if cfg.JWTSecret != "dev-secret" {
		t.Errorf("expected JWTSecret 'dev-secret', got '%s'", cfg.JWTSecret)
	}
	if cfg.JWTExpiresIn != 24*time.Hour {
		t.Errorf("expected JWTExpiresIn 24h, got %v", cfg.JWTExpiresIn)
	}
	if cfg.MarketplaceCommission != 2.5 {
		t.Errorf("expected MarketplaceCommission 2.5, got %f", cfg.MarketplaceCommission)
	}
	if len(cfg.CORSOrigins) != 1 || cfg.CORSOrigins[0] != "*" {
		t.Errorf("expected CORSOrigins ['*'], got %v", cfg.CORSOrigins)
	}
}

func TestLoadFromEnv(t *testing.T) {
	os.Setenv("APP_NAME", "test-app")
	os.Setenv("PORT", "9999")
	os.Setenv("DATABASE_URL", "postgres://test:test@localhost:5432/test")
	os.Setenv("DB_MAX_OPEN_CONNS", "100")
	os.Setenv("DB_MAX_IDLE_CONNS", "50")
	os.Setenv("DB_CONN_MAX_IDLE", "10m")
	os.Setenv("MARKETPLACE_COMMISSION", "5.0")
	os.Setenv("JWT_SECRET", "super-secret")
	os.Setenv("JWT_EXPIRES_IN", "12h")
	os.Setenv("PASSWORD_PEPPER", "pepper123")
	os.Setenv("CORS_ORIGINS", "https://example.com,https://app.example.com")

	defer func() {
		os.Unsetenv("APP_NAME")
		os.Unsetenv("PORT")
		os.Unsetenv("DATABASE_URL")
		os.Unsetenv("DB_MAX_OPEN_CONNS")
		os.Unsetenv("DB_MAX_IDLE_CONNS")
		os.Unsetenv("DB_CONN_MAX_IDLE")
		os.Unsetenv("MARKETPLACE_COMMISSION")
		os.Unsetenv("JWT_SECRET")
		os.Unsetenv("JWT_EXPIRES_IN")
		os.Unsetenv("PASSWORD_PEPPER")
		os.Unsetenv("CORS_ORIGINS")
	}()

	cfg := Load()

	if cfg.AppName != "test-app" {
		t.Errorf("expected AppName 'test-app', got '%s'", cfg.AppName)
	}
	if cfg.Port != "9999" {
		t.Errorf("expected Port '9999', got '%s'", cfg.Port)
	}
	if cfg.DatabaseURL != "postgres://test:test@localhost:5432/test" {
		t.Errorf("expected custom DatabaseURL, got '%s'", cfg.DatabaseURL)
	}
	if cfg.MaxOpenConns != 100 {
		t.Errorf("expected MaxOpenConns 100, got %d", cfg.MaxOpenConns)
	}
	if cfg.MaxIdleConns != 50 {
		t.Errorf("expected MaxIdleConns 50, got %d", cfg.MaxIdleConns)
	}
	if cfg.ConnMaxIdle != 10*time.Minute {
		t.Errorf("expected ConnMaxIdle 10m, got %v", cfg.ConnMaxIdle)
	}
	if cfg.MarketplaceCommission != 5.0 {
		t.Errorf("expected MarketplaceCommission 5.0, got %f", cfg.MarketplaceCommission)
	}
	if cfg.JWTSecret != "super-secret" {
		t.Errorf("expected JWTSecret 'super-secret', got '%s'", cfg.JWTSecret)
	}
	if cfg.JWTExpiresIn != 12*time.Hour {
		t.Errorf("expected JWTExpiresIn 12h, got %v", cfg.JWTExpiresIn)
	}
	if cfg.PasswordPepper != "pepper123" {
		t.Errorf("expected PasswordPepper 'pepper123', got '%s'", cfg.PasswordPepper)
	}
	if len(cfg.CORSOrigins) != 2 {
		t.Errorf("expected 2 CORS origins, got %d", len(cfg.CORSOrigins))
	}
}

func TestAddr(t *testing.T) {
	cfg := Config{Port: "3000"}
	expected := ":3000"
	if cfg.Addr() != expected {
		t.Errorf("expected Addr '%s', got '%s'", expected, cfg.Addr())
	}
}

func TestInvalidEnvValues(t *testing.T) {
	os.Setenv("DB_MAX_OPEN_CONNS", "not-a-number")
	os.Setenv("MARKETPLACE_COMMISSION", "invalid")
	os.Setenv("DB_CONN_MAX_IDLE", "bad-duration")

	defer func() {
		os.Unsetenv("DB_MAX_OPEN_CONNS")
		os.Unsetenv("MARKETPLACE_COMMISSION")
		os.Unsetenv("DB_CONN_MAX_IDLE")
	}()

	cfg := Load()

	// Should use defaults when values are invalid
	if cfg.MaxOpenConns != 15 {
		t.Errorf("expected fallback MaxOpenConns 15, got %d", cfg.MaxOpenConns)
	}
	if cfg.MarketplaceCommission != 2.5 {
		t.Errorf("expected fallback MarketplaceCommission 2.5, got %f", cfg.MarketplaceCommission)
	}
	if cfg.ConnMaxIdle != 5*time.Minute {
		t.Errorf("expected fallback ConnMaxIdle 5m, got %v", cfg.ConnMaxIdle)
	}
}

func TestEmptyCORSOrigins(t *testing.T) {
	os.Setenv("CORS_ORIGINS", "")
	defer os.Unsetenv("CORS_ORIGINS")

	cfg := Load()

	if len(cfg.CORSOrigins) != 1 || cfg.CORSOrigins[0] != "*" {
		t.Errorf("expected fallback CORSOrigins ['*'], got %v", cfg.CORSOrigins)
	}
}
