package config

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

// Config 应用配置
type Config struct {
	DatabaseURL    string
	ListenAddr     string
	APIKey         string
	ReturnSecret   bool
	MaxConcurrency int
	MaxTestLimit   int
	LeaseTTL       time.Duration

	// Telegram Bot 配置
	TelegramBotToken          string
	TelegramAdminIDs          []int64
	TelegramNotifyChatID      string
	TelegramTestIntervalMin   int
	TelegramAlertThreshold    int
	TelegramTestURL           string
	TelegramTestTimeoutMs     int
}

// Load 从环境变量加载配置
func Load() *Config {
	cfg := &Config{
		DatabaseURL:    getEnv("DATABASE_URL", "postgres://postgres:postgres@localhost:5432/proxyrotator?sslmode=disable"),
		ListenAddr:     getEnv("LISTEN_ADDR", ":8080"),
		APIKey:         getEnv("API_KEY", ""),
		ReturnSecret:   getEnvBool("RETURN_SECRET", true),
		MaxConcurrency: getEnvInt("MAX_CONCURRENCY", 200),
		MaxTestLimit:   getEnvInt("MAX_TEST_LIMIT", 2000),
		LeaseTTL:       getEnvDuration("LEASE_TTL", 60*time.Second),

		// Telegram
		TelegramBotToken:          getEnv("TELEGRAM_BOT_TOKEN", ""),
		TelegramAdminIDs:          getEnvInt64Slice("TELEGRAM_ADMIN_IDS", nil),
		TelegramNotifyChatID:      getEnv("TELEGRAM_NOTIFY_CHAT_ID", ""),
		TelegramTestIntervalMin:   getEnvInt("TELEGRAM_TEST_INTERVAL_MIN", 60),
		TelegramAlertThreshold:    getEnvInt("TELEGRAM_ALERT_THRESHOLD", 50),
		TelegramTestURL:           getEnv("TELEGRAM_TEST_URL", "https://httpbin.org/ip"),
		TelegramTestTimeoutMs:     getEnvInt("TELEGRAM_TEST_TIMEOUT_MS", 5000),
	}
	return cfg
}

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

func getEnvBool(key string, defaultValue bool) bool {
	if v := os.Getenv(key); v != "" {
		b, err := strconv.ParseBool(v)
		if err == nil {
			return b
		}
	}
	return defaultValue
}

func getEnvInt(key string, defaultValue int) int {
	if v := os.Getenv(key); v != "" {
		i, err := strconv.Atoi(v)
		if err == nil {
			return i
		}
	}
	return defaultValue
}

func getEnvDuration(key string, defaultValue time.Duration) time.Duration {
	if v := os.Getenv(key); v != "" {
		d, err := time.ParseDuration(v)
		if err == nil {
			return d
		}
	}
	return defaultValue
}

func getEnvInt64Slice(key string, defaultValue []int64) []int64 {
	v := os.Getenv(key)
	if v == "" {
		return defaultValue
	}
	parts := splitAndTrim(v, ",")
	result := make([]int64, 0, len(parts))
	for _, p := range parts {
		if p == "" {
			continue
		}
		i, err := strconv.ParseInt(p, 10, 64)
		if err == nil {
			result = append(result, i)
		}
	}
	return result
}

func splitAndTrim(s, sep string) []string {
	parts := make([]string, 0)
	for _, p := range stringsSplit(s, sep) {
		p = stringsTrim(p)
		if p != "" {
			parts = append(parts, p)
		}
	}
	return parts
}

func stringsSplit(s, sep string) []string {
	if s == "" {
		return nil
	}
	result := make([]string, 0)
	start := 0
	for i := 0; i < len(s); i++ {
		if i+len(sep) <= len(s) && s[i:i+len(sep)] == sep {
			result = append(result, s[start:i])
			start = i + len(sep)
			i += len(sep) - 1
		}
	}
	result = append(result, s[start:])
	return result
}

func stringsTrim(s string) string {
	start, end := 0, len(s)
	for start < end && (s[start] == ' ' || s[start] == '\t') {
		start++
	}
	for end > start && (s[end-1] == ' ' || s[end-1] == '\t') {
		end--
	}
	return s[start:end]
}
