package config

import (
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/joho/godotenv"
)

type Config struct {
	DBHost     string
	DBPort     string
	DBUser     string
	DBPass     string
	DBName     string
	RedisHost  string
	RedisPort  string
	RedisPass  string
	RedisDB    int
	JWTSecret  string
	AppPort    string
	AppURL     string
	LogLevel   string
	PluginRoot string
}

var AppConfig *Config

func LoadConfig() {
	err := godotenv.Load()
	if err != nil {
		log.Println("No .env file found, using environment variables")
	}

	AppConfig = &Config{
		DBHost:     getEnv("DB_HOST", "localhost"),
		DBPort:     getEnv("DB_PORT", "3306"),
		DBUser:     getEnv("DB_USER", "root"),
		DBPass:     getEnv("DB_PASS", ""),
		DBName:     getEnv("DB_NAME", "xboard"),
		RedisHost:  getEnv("REDIS_HOST", "localhost"),
		RedisPort:  getEnv("REDIS_PORT", "6379"),
		RedisPass:  getEnv("REDIS_PASS", ""),
		RedisDB:    getEnvInt("REDIS_DB", 0),
		JWTSecret:  getEnv("JWT_SECRET", "secret"),
		AppPort:    getEnv("APP_PORT", "8080"),
		AppURL:     getEnv("APP_URL", ""),
		LogLevel:   NormalizeLogLevel(getEnv("LOG_LEVEL", "info")),
		PluginRoot: getEnv("PLUGIN_ROOT", "reference\\LDNET-GA-Theme\\plugin"),
	}
}

func NormalizeLogLevel(value string) string {
	switch strings.ToLower(strings.TrimSpace(value)) {
	case "debug":
		return "debug"
	case "warn", "warning":
		return "warn"
	case "error":
		return "error"
	case "silent":
		return "silent"
	default:
		return "info"
	}
}

func IsLogLevelEnabled(currentLevel, targetLevel string) bool {
	logLevelOrder := map[string]int{
		"debug":  0,
		"info":   1,
		"warn":   2,
		"error":  3,
		"silent": 4,
	}

	currentRank, ok := logLevelOrder[NormalizeLogLevel(currentLevel)]
	if !ok {
		currentRank = logLevelOrder["info"]
	}
	targetRank, ok := logLevelOrder[NormalizeLogLevel(targetLevel)]
	if !ok {
		targetRank = logLevelOrder["info"]
	}

	return currentRank <= targetRank
}

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

func getEnvInt(key string, defaultValue int) int {
	raw := getEnv(key, "")
	if raw == "" {
		return defaultValue
	}

	value, err := strconv.Atoi(raw)
	if err != nil {
		return defaultValue
	}

	return value
}
