package config

import (
	"os"
	"strconv"
	"strings"
	"time"
)

// Load reads configuration from environment variables with safe defaults.
func Load() Config {
	return Config{
		HTTPAddr:         getEnv("HTTP_ADDR", ":8080"),
		OPABaseURL:       getEnv("OPA_URL", "http://localhost:8181"),
		OPADecisionPath:  getEnv("OPA_DECISION_PATH", "acp/decision"),
		OPAHTTPTimeout:   getEnvDuration("OPA_HTTP_TIMEOUT_MS", 5000),
		PoliciesDir:      getEnv("POLICIES_DIR", ""),
		APIKey:           os.Getenv("API_KEY"),
		Environment:      getEnv("ENVIRONMENT", "development"),
		CORSAllowOrigins: corsAllowOrigins(),
		JWTEnabled:       envBool("JWT_ENABLED", false),
		JWTRequired:      envBool("JWT_REQUIRED", false),
		JWTIssuer:        getEnv("JWT_ISSUER", "acp-dev"),
		JWTAudience:      getEnv("JWT_AUDIENCE", "acp-interceptor"),
		JWTPublicKeyPath: os.Getenv("JWT_PUBLIC_KEY_PATH"),
		JWTPublicKeyPEM:  os.Getenv("JWT_PUBLIC_KEY_PEM"),
		DatabaseURL:          strings.TrimSpace(os.Getenv("DATABASE_URL")),
		AgentRegistryEnforce: agentRegistryEnforce(),
		SeedDemoAgents:       envBool("ACP_SEED_DEMO_AGENTS", false),
	}
}

func agentRegistryEnforce() bool {
	if v := strings.TrimSpace(os.Getenv("AGENT_REGISTRY_ENFORCE")); v != "" {
		return envBool("AGENT_REGISTRY_ENFORCE", false)
	}
	// Default: enforce when Postgres registry is enabled.
	return strings.TrimSpace(os.Getenv("DATABASE_URL")) != ""
}

func corsAllowOrigins() string {
	if v := os.Getenv("CORS_ALLOW_ORIGINS"); v != "" {
		return v
	}
	if getEnv("ENVIRONMENT", "development") == "development" {
		return "http://localhost:3000,http://127.0.0.1:3000,http://localhost:3001,http://127.0.0.1:3001"
	}
	return ""
}

func getEnv(key, def string) string {
	if v := os.Getenv(key); v != "" {
		return v
	}
	return def
}

func envBool(key string, def bool) bool {
	v := strings.TrimSpace(os.Getenv(key))
	if v == "" {
		return def
	}
	switch strings.ToLower(v) {
	case "1", "true", "yes", "on":
		return true
	case "0", "false", "no", "off":
		return false
	default:
		return def
	}
}

func getEnvDuration(key string, defMS int) time.Duration {
	v := os.Getenv(key)
	if v == "" {
		return time.Duration(defMS) * time.Millisecond
	}
	ms, err := strconv.Atoi(v)
	if err != nil || ms <= 0 {
		return time.Duration(defMS) * time.Millisecond
	}
	return time.Duration(ms) * time.Millisecond
}
