package config

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

// Config holds all application configuration
type Config struct {
	Server   ServerConfig
	Template TemplateConfig
	Data     DataConfig
}

// ServerConfig contains server-specific settings
type ServerConfig struct {
	Port         string
	Host         string
	ReadTimeout  int
	WriteTimeout int
}

// TemplateConfig contains template-specific settings
type TemplateConfig struct {
	Dir         string
	PartialsDir string
	HotReload   bool
}

// DataConfig contains data directory settings
type DataConfig struct {
	Dir string
}

// Load creates a new Config with values from environment or defaults
func Load() *Config {
	return &Config{
		Server: ServerConfig{
			Port:         getEnv("PORT", "1999"),
			Host:         getEnv("HOST", "localhost"),
			ReadTimeout:  getEnvAsInt("READ_TIMEOUT", 15),
			WriteTimeout: getEnvAsInt("WRITE_TIMEOUT", 15),
		},
		Template: TemplateConfig{
			Dir:         getEnv("TEMPLATE_DIR", "templates"),
			PartialsDir: getEnv("PARTIALS_DIR", "templates/partials"),
			HotReload:   getEnvAsBool("TEMPLATE_HOT_RELOAD", isDevelopment()),
		},
		Data: DataConfig{
			Dir: getEnv("DATA_DIR", "data"),
		},
	}
}

// Address returns the server address in host:port format
func (c *Config) Address() string {
	return fmt.Sprintf("%s:%s", c.Server.Host, c.Server.Port)
}

// Helper functions

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

func getEnvAsInt(key string, defaultValue int) int {
	valueStr := os.Getenv(key)
	if value, err := strconv.Atoi(valueStr); err == nil {
		return value
	}
	return defaultValue
}

func getEnvAsBool(key string, defaultValue bool) bool {
	valueStr := os.Getenv(key)
	if value, err := strconv.ParseBool(valueStr); err == nil {
		return value
	}
	return defaultValue
}

func isDevelopment() bool {
	env := getEnv("GO_ENV", "development")
	return env == "development" || env == "dev"
}
