package config

import (
	"os"
	"strings"
)

const (
	// EnvDevelopment représente l'environnement de développement (T0039)
	EnvDevelopment = "development"
	// EnvStaging représente l'environnement de staging (T0039)
	EnvStaging = "staging"
	// EnvProduction représente l'environnement de production (T0039)
	EnvProduction = "production"
	// EnvTest représente l'environnement de test (T0039)
	EnvTest = "test"
)

var validEnvironments = []string{
	EnvDevelopment,
	EnvStaging,
	EnvProduction,
	EnvTest,
}

// DetectEnvironment détecte l'environnement actuel avec fallback intelligent (T0039)
// Priorité: APP_ENV > NODE_ENV > GO_ENV > hostname > development
func DetectEnvironment() string {
	// 1. APP_ENV (priorité)
	if env := os.Getenv("APP_ENV"); env != "" {
		env = strings.TrimSpace(env)
		if isValidEnvironment(env) {
			return strings.ToLower(env)
		}
	}

	// 2. NODE_ENV (compatibilité)
	if env := os.Getenv("NODE_ENV"); env != "" {
		env = strings.TrimSpace(env)
		if isValidEnvironment(env) {
			return strings.ToLower(env)
		}
	}

	// 3. GO_ENV (compatibilité Go)
	if env := os.Getenv("GO_ENV"); env != "" {
		env = strings.TrimSpace(env)
		if isValidEnvironment(env) {
			return strings.ToLower(env)
		}
	}

	// 4. Fallback: détection par hostname (production si contient "prod")
	if hostname, err := os.Hostname(); err == nil {
		hostnameLower := strings.ToLower(hostname)
		if strings.Contains(hostnameLower, "prod") || strings.Contains(hostnameLower, "production") {
			return EnvProduction
		}
		if strings.Contains(hostnameLower, "staging") || strings.Contains(hostnameLower, "stage") {
			return EnvStaging
		}
	}

	// 5. Fallback par défaut: development
	return EnvDevelopment
}

// isValidEnvironment vérifie qu'un environnement est valide (T0039)
func isValidEnvironment(env string) bool {
	envLower := strings.ToLower(strings.TrimSpace(env))
	for _, validEnv := range validEnvironments {
		if envLower == validEnv {
			return true
		}
	}
	return false
}

// NormalizeEnvironment normalise le nom d'environnement (T0039)
// Convertit les alias courants (dev, prod, stage, etc.) en noms canoniques
func NormalizeEnvironment(env string) string {
	envLower := strings.ToLower(strings.TrimSpace(env))

	// Mappings courants
	mappings := map[string]string{
		"dev":         EnvDevelopment,
		"prod":        EnvProduction,
		"stage":       EnvStaging,
		"stg":         EnvStaging,
		"test":        EnvTest,
		"local":       EnvDevelopment,
		"staging":     EnvStaging,
		"production":  EnvProduction,
		"development": EnvDevelopment,
	}

	if normalized, ok := mappings[envLower]; ok {
		return normalized
	}

	// Si déjà valide, retourner tel quel
	if isValidEnvironment(envLower) {
		return envLower
	}

	// Fallback
	return EnvDevelopment
}
