package config

import (
	"fmt"
	"os"
	"strconv"
	"time"
)

// Config holds runtime configuration loaded from environment variables.
type Config struct {
	AppName              string
	NodeID               string
	ControlPlaneURL      string
	NodeToken            string
	HealthListenAddr     string
	HeartbeatInterval    time.Duration
	ReconnectBackoff     time.Duration
	DataDir              string
	DockerSocket         string
	LogLevel             string
	TLSCertFile          string
	TLSKeyFile           string
	TLSCAFile            string
	TLSSkipVerify        bool
	ShutdownGracePeriod  time.Duration
}

// Load reads configuration from environment variables with sensible defaults for development.
func Load() (*Config, error) {
	cfg := &Config{
		AppName:             envOrDefault("APP_NAME", "HexaHost GameCloud"),
		NodeID:              os.Getenv("NODE_ID"),
		ControlPlaneURL:     os.Getenv("NODE_AGENT_PUBLIC_URL"),
		NodeToken:           os.Getenv("NODE_TOKEN"),
		HealthListenAddr:    envOrDefault("NODE_AGENT_HEALTH_ADDR", ":9100"),
		HeartbeatInterval:   durationFromEnv("NODE_HEARTBEAT_INTERVAL", 10*time.Second),
		ReconnectBackoff:    durationFromEnv("NODE_RECONNECT_BACKOFF", 5*time.Second),
		DataDir:             envOrDefault("NODE_DATA_DIR", "/var/lib/hexahost-gamecloud"),
		DockerSocket:        envOrDefault("DOCKER_HOST", "unix:///var/run/docker.sock"),
		LogLevel:            envOrDefault("LOG_LEVEL", "info"),
		TLSCertFile:         os.Getenv("NODE_TLS_CERT"),
		TLSKeyFile:          os.Getenv("NODE_TLS_KEY"),
		TLSCAFile:           os.Getenv("NODE_CA_CERT"),
		TLSSkipVerify:       boolFromEnv("NODE_TLS_SKIP_VERIFY", false),
		ShutdownGracePeriod: durationFromEnv("NODE_SHUTDOWN_GRACE", 30*time.Second),
	}

	if cfg.NodeID == "" {
		return nil, fmt.Errorf("NODE_ID is required")
	}
	if cfg.ControlPlaneURL == "" {
		return nil, fmt.Errorf("NODE_AGENT_PUBLIC_URL is required")
	}

	return cfg, nil
}

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

func durationFromEnv(key string, fallback time.Duration) time.Duration {
	raw := os.Getenv(key)
	if raw == "" {
		return fallback
	}
	d, err := time.ParseDuration(raw)
	if err != nil {
		return fallback
	}
	return d
}

func boolFromEnv(key string, fallback bool) bool {
	raw := os.Getenv(key)
	if raw == "" {
		return fallback
	}
	v, err := strconv.ParseBool(raw)
	if err != nil {
		return fallback
	}
	return v
}
