package config

import (
	"os"
	"path/filepath"
	"strconv"
)

// Config holds all runtime configuration resolved from environment variables.
type Config struct {
	Port       int
	AdminToken string
	WorksDir   string
	ConfigDir  string
	Debug      bool
}

// Load reads environment variables and returns a fully-populated Config.
//
// Directory resolution priority:
//  1. SPROUTWORKCOLLECT_WORKS_DIR / SPROUTWORKCOLLECT_CONFIG_DIR  (per-dir override)
//  2. SPROUTWORKCOLLECT_DATA_DIR / DATA_DIR  (data root, works/ and config/ appended)
//  3. ./data/works and ./data/config  (relative to current working directory)
func Load() *Config {
	loadDotEnv()

	cfg := &Config{
		Port:       5000,
		// Do not commit real admin tokens; override via ADMIN_TOKEN / SPROUTWORKCOLLECT_ADMIN_TOKEN.
		AdminToken: "change-me",
	}

	if v := os.Getenv("PORT"); v != "" {
		if p, err := strconv.Atoi(v); err == nil {
			cfg.Port = p
		}
	}

	if v := firstEnv("SPROUTWORKCOLLECT_ADMIN_TOKEN", "ADMIN_TOKEN"); v != "" {
		cfg.AdminToken = v
	}

	dbg := os.Getenv("GIN_DEBUG")
	cfg.Debug = dbg == "1" || dbg == "true"

	dataDir := firstEnv("SPROUTWORKCOLLECT_DATA_DIR", "DATA_DIR")

	worksDir := firstEnv("SPROUTWORKCOLLECT_WORKS_DIR", "WORKS_DIR")
	if worksDir == "" {
		if dataDir != "" {
			worksDir = filepath.Join(dataDir, "works")
		} else {
			wd, _ := os.Getwd()
			worksDir = filepath.Join(wd, "data", "works")
		}
	}

	configDir := firstEnv("SPROUTWORKCOLLECT_CONFIG_DIR", "CONFIG_DIR")
	if configDir == "" {
		if dataDir != "" {
			configDir = filepath.Join(dataDir, "config")
		} else {
			wd, _ := os.Getwd()
			configDir = filepath.Join(wd, "data", "config")
		}
	}

	cfg.WorksDir = filepath.Clean(worksDir)
	cfg.ConfigDir = filepath.Clean(configDir)

	return cfg
}

func firstEnv(keys ...string) string {
	for _, k := range keys {
		if v := os.Getenv(k); v != "" {
			return v
		}
	}
	return ""
}
