package config

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

func TestReadEnv(t *testing.T) {
	// Set up environment variables
	os.Setenv("CONFIG_PATH", "/path/to/config")
	os.Setenv("ENV", "dev")
	os.Setenv("PORT", "80")
	os.Setenv("BASE_URL", "https://example.com")
	os.Setenv("ACCESS_ORIGIN", "lou-taylor.ch")
	os.Setenv("DB_HOST", "localhost")
	os.Setenv("DB_PORT", "5432")
	os.Setenv("DB_USER", "testuser")
	os.Setenv("DB_PASSWORD", "password")
	os.Setenv("DB_NAME", "testdb")
	os.Setenv("ADMIN_NAME", "admin")
	os.Setenv("ADMIN_PASSWORD", "adminpass")
	os.Setenv("JWT_SECRET", "supersecret")
	os.Setenv("JWT_VALID_PERIOD", "24h")
	os.Setenv("IMAGE_QUALITY", "85.5")
	os.Setenv("IMAGE_MAX_WIDTH", "1920")
	os.Setenv("IMAGE_SAVE_PATH", "/path/to/images")

	// Initialize an empty Config struct
	c := New()

	// Call ReadEnv to populate the config from environment variables
	err := c.ReadEnv()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if c.BaseUrl != "https://example.com" {
		t.Errorf("expected BaseUrl to be 'https://example.com', got %v", c.BaseUrl)
	}
	if c.Port != 80 {
		t.Errorf("expected Port to be 80, got %d", c.Port)
	}

}

func TestHelperFunctions(t *testing.T) {
	t.Run("stringVar", func(t *testing.T) {
		// Set up environment variable
		os.Setenv("TEST_STRING", "test_value")

		var result string
		stringVar(&result, "TEST_STRING")

		if result != "test_value" {
			t.Errorf("expected 'test_value', got '%v'", result)
		}

		// Test empty environment variable case
		os.Setenv("TEST_STRING_EMPTY", "")
		stringVar(&result, "TEST_STRING_EMPTY")

		if result != "test_value" { // result shouldn't change
			t.Errorf("expected 'test_value', got '%v'", result)
		}
	})

	t.Run("float64Var", func(t *testing.T) {
		// Set up valid float environment variable
		os.Setenv("TEST_FLOAT", "42.42")

		var result float64
		err := float64Var(&result, "TEST_FLOAT")
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		if result != 42.42 {
			t.Errorf("expected 42.42, got '%v'", result)
		}

		// Test invalid float value
		os.Setenv("TEST_FLOAT_INVALID", "invalid_float")
		err = float64Var(&result, "TEST_FLOAT_INVALID")
		if err == nil {
			t.Errorf("expected error for invalid float, but got nil")
		}
	})

	t.Run("intVar", func(t *testing.T) {
		// Set up valid integer environment variable
		os.Setenv("TEST_INT", "123")

		var result int
		err := intVar(&result, "TEST_INT")
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		if result != 123 {
			t.Errorf("expected 123, got '%v'", result)
		}

		// Test invalid int value
		os.Setenv("TEST_INT_INVALID", "invalid_int")
		err = intVar(&result, "TEST_INT_INVALID")
		if err == nil {
			t.Errorf("expected error for invalid int, but got nil")
		}
	})

	t.Run("durationVar", func(t *testing.T) {
		// Set up valid duration environment variable
		os.Setenv("TEST_DURATION", "2h")

		var result time.Duration
		err := durationVar(&result, "TEST_DURATION")
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		expectedDuration := 2 * time.Hour
		if result != expectedDuration {
			t.Errorf("expected %v, got '%v'", expectedDuration, result)
		}

		// Test invalid duration value
		os.Setenv("TEST_DURATION_INVALID", "invalid_duration")
		err = durationVar(&result, "TEST_DURATION_INVALID")
		if err == nil {
			t.Errorf("expected error for invalid duration, but got nil")
		}
	})
}
