package config

import (
	"log"
	"os"
	"strconv"

	"github.com/joho/godotenv"
)

type Config struct {
	AppEnv              string
	AppPort             string
	DBDsn               string
	JwtAccessSecret     string
	JwtRefreshSecret    string
	JwtAccessTTLMinutes int
	JwtRefreshTTLDays   int
	CorsAllowedOrigins  string
	SwaggerHost         string
	S3Endpoint          string
	S3AccessKey         string
	S3SecretKey         string
	S3Bucket            string
	S3Region            string
	FrontendURL         string
}

func LoadConfig() *Config {
	err := godotenv.Load()
	if err != nil {
		log.Println("Warning: .env file not found")
	}

	return &Config{
		AppEnv:              getEnv("APP_ENV", "dev"),
		AppPort:             getEnvWithFallback("PORT", "APP_PORT", "8080"),
		DBDsn:               getEnv("DB_DSN", ""),
		JwtAccessSecret:     getEnv("JWT_ACCESS_SECRET", "secret"),
		JwtRefreshSecret:    getEnv("JWT_REFRESH_SECRET", "refresh_secret"),
		JwtAccessTTLMinutes: getEnvAsInt("JWT_ACCESS_TTL_MINUTES", 15),
		JwtRefreshTTLDays:   getEnvAsInt("JWT_REFRESH_TTL_DAYS", 30),
		CorsAllowedOrigins:  getEnv("CORS_ALLOWED_ORIGINS", "*"),
		SwaggerHost:         getEnv("SWAGGER_HOST", "localhost:8080"),
		S3Endpoint:          getEnv("S3_ENDPOINT", ""),
		S3AccessKey:         getEnv("S3_ACCESS_KEY", ""),
		S3SecretKey:         getEnv("S3_SECRET_KEY", ""),
		S3Bucket:            getEnv("S3_BUCKET", ""),
		S3Region:            getEnv("S3_REGION", "nyc1"),
		FrontendURL:         getEnv("FRONTEND_URL", "http://localhost:3000"),
	}
}

func getEnv(key, fallback string) string {
	if value, ok := os.LookupEnv(key); ok {
		return value
	}
	return fallback
}

func getEnvAsInt(key string, fallback int) int {
	strValue := getEnv(key, "")
	if value, err := strconv.Atoi(strValue); err == nil {
		return value
	}
	return fallback
}

// getEnvWithFallback tenta a primeira variável, depois a segunda, depois o fallback
// Útil para compatibilidade com Dokku (PORT) e desenvolvimento local (APP_PORT)
func getEnvWithFallback(primary, secondary, fallback string) string {
	if value, ok := os.LookupEnv(primary); ok {
		return value
	}
	if value, ok := os.LookupEnv(secondary); ok {
		return value
	}
	return fallback
}
