package config

import (
	"crypto/sha256"
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"sync"
)

const DefaultPassword = "goproxy"

func dataDir() string {
	if d := os.Getenv("DATA_DIR"); d != "" {
		os.MkdirAll(d, 0755)
		return d + "/"
	}
	return ""
}

func ConfigFile() string { return dataDir() + "config.json" }

type Config struct {
	// WebUI 端口
	WebUIPort string

	// WebUI 密码 SHA256 哈希
	WebUIPasswordHash string

	// 代理池本地监听端口（随机轮换模式）
	ProxyPort string

	// 稳定代理端口（最低延迟模式）
	StableProxyPort string

	// 代理服务认证配置
	ProxyAuthEnabled      bool   // 是否启用代理认证（默认 false）
	ProxyAuthUsername     string // 代理认证用户名（默认 "proxy"）
	ProxyAuthPasswordHash string // 代理认证密码 SHA256 哈希

	// 地理过滤配置
	BlockedCountries []string // 屏蔽的国家代码列表（如 ["CN", "RU"]，默认 ["CN"]）

	// SQLite 数据库路径
	DBPath string

	// ========== 池子容量配置 ==========
	PoolMaxSize        int     // 代理池总容量（默认100）
	PoolHTTPRatio      float64 // HTTP协议占比（默认0.5）
	PoolMinPerProtocol int     // 每协议最小保证（默认10）

	// ========== 延迟标准配置 ==========
	MaxLatencyMs          int // 标准模式最大延迟（默认2000ms）
	MaxLatencyEmergency   int // 紧急模式放宽延迟（默认3000ms）
	MaxLatencyHealthy     int // 健康模式严格延迟（默认1500ms）
	MaxLatencyDegradation int // 降级模式超宽松延迟（默认5000ms）

	// ========== 验证配置 ==========
	ValidateConcurrency int    // 验证并发数（默认300）
	ValidateTimeout     int    // 验证超时（秒）（默认8）
	ValidateURL         string // 验证目标 URL

	// ========== 健康检查配置 ==========
	HealthCheckInterval   int // 状态监控间隔（分钟）（默认5）
	HealthCheckBatchSize  int // 每批验证数量（默认20）
	HealthCheckConcurrency int // 批次内并发数（默认50）

	// ========== 优化配置 ==========
	OptimizeInterval    int     // 优化轮换间隔（分钟）（默认30）
	OptimizeConcurrency int     // 优化时并发数（默认100）
	ReplaceThreshold    float64 // 替换阈值（默认0.7，新代理需快30%）

	// ========== IP查询配置 ==========
	IPQueryRateLimit int // IP查询限流（次/秒）（默认10）

	// ========== 源管理配置 ==========
	SourceFailThreshold    int // 源降级阈值（默认3）
	SourceDisableThreshold int // 源禁用阈值（默认5）
	SourceCooldownMinutes  int // 源禁用冷却时间（默认30）

	// ========== 兼容旧配置 ==========
	MaxResponseMs int // 已废弃，使用 MaxLatencyMs 替代
	MaxFailCount  int // 代理失败次数阈值
	MaxRetry      int // 请求失败后的重试次数
	FetchInterval int // 已废弃，由智能抓取器管理
	CheckInterval int // 已废弃，由 HealthCheckInterval 替代

	// 代理来源 URL（已废弃，内置多源）
	HTTPSourceURL   string
	SOCKS5SourceURL string
}

var (
	globalCfg *Config
	cfgMu     sync.RWMutex
)

func passwordHash(plain string) string {
	return fmt.Sprintf("%x", sha256.Sum256([]byte(plain)))
}

func DefaultConfig() *Config {
	// 优先从环境变量 WEBUI_PASSWORD 读取密码，未设置时使用默认密码
	password := os.Getenv("WEBUI_PASSWORD")
	if password == "" {
		password = DefaultPassword
	}
	
	// 读取代理认证配置
	proxyAuthEnabled := os.Getenv("PROXY_AUTH_ENABLED") == "true"
	proxyAuthUsername := os.Getenv("PROXY_AUTH_USERNAME")
	if proxyAuthUsername == "" {
		proxyAuthUsername = "proxy"
	}
	proxyAuthPassword := os.Getenv("PROXY_AUTH_PASSWORD")
	proxyAuthHash := ""
	if proxyAuthPassword != "" {
		proxyAuthHash = passwordHash(proxyAuthPassword)
	}
	
	// 读取地理过滤配置
	blockedCountries := []string{"CN"} // 默认屏蔽中国大陆
	if blockedEnv := os.Getenv("BLOCKED_COUNTRIES"); blockedEnv != "" {
		// 支持逗号分隔的国家代码，如 "CN,RU,KP"
		countries := strings.Split(blockedEnv, ",")
		blockedCountries = make([]string, 0, len(countries))
		for _, c := range countries {
			c = strings.TrimSpace(strings.ToUpper(c))
			if c != "" {
				blockedCountries = append(blockedCountries, c)
			}
		}
	}
	
	return &Config{
		// 基础服务配置
		WebUIPort:         ":7778",
		WebUIPasswordHash: passwordHash(password),
		ProxyPort:         ":7777",
		StableProxyPort:   ":7776",
		DBPath:            dataDir() + "proxy.db",
		
		// 代理认证配置
		ProxyAuthEnabled:      proxyAuthEnabled,
		ProxyAuthUsername:     proxyAuthUsername,
		ProxyAuthPasswordHash: proxyAuthHash,
		
		// 地理过滤配置
		BlockedCountries: blockedCountries,

		// 池子容量配置
		PoolMaxSize:        100,  // 总容量
		PoolHTTPRatio:      0.5,  // HTTP占50%
		PoolMinPerProtocol: 10,   // 每协议最少10个

		// 延迟标准配置
		MaxLatencyMs:          2000, // 标准2秒
		MaxLatencyEmergency:   3000, // 紧急3秒
		MaxLatencyHealthy:     1500, // 健康1.5秒
		MaxLatencyDegradation: 5000, // 降级5秒

		// 验证配置
		ValidateConcurrency: 300,
		ValidateTimeout:     8,
		ValidateURL:         "http://www.gstatic.com/generate_204",

		// 健康检查配置
		HealthCheckInterval:    5,  // 5分钟
		HealthCheckBatchSize:   20, // 每批20个
		HealthCheckConcurrency: 50, // 批次并发50

		// 优化配置
		OptimizeInterval:    30,  // 30分钟
		OptimizeConcurrency: 100, // 并发100
		ReplaceThreshold:    0.7, // 新代理需快30%

		// IP查询配置
		IPQueryRateLimit: 10, // 10次/秒

		// 源管理配置
		SourceFailThreshold:    3,  // 失败3次降级
		SourceDisableThreshold: 5,  // 失败5次禁用
		SourceCooldownMinutes:  30, // 禁用30分钟

		// 兼容旧配置
		MaxResponseMs: 5000,
		MaxFailCount:  3,
		MaxRetry:      3,
		FetchInterval: 30,
		CheckInterval: 10,
		HTTPSourceURL: "https://cdn.jsdelivr.net/gh/databay-labs/free-proxy-list/http.txt",
		SOCKS5SourceURL: "https://cdn.jsdelivr.net/gh/databay-labs/free-proxy-list/socks5.txt",
	}
}

// Load 从文件加载配置，文件不存在则用默认值
func Load() *Config {
	cfg := DefaultConfig()
	data, err := os.ReadFile(ConfigFile())
	if err == nil {
		var saved savedConfig
		if json.Unmarshal(data, &saved) == nil {
			// 池子配置
			if saved.PoolMaxSize > 0 {
				cfg.PoolMaxSize = saved.PoolMaxSize
			}
			if saved.PoolHTTPRatio > 0 && saved.PoolHTTPRatio <= 1 {
				cfg.PoolHTTPRatio = saved.PoolHTTPRatio
			}
			if saved.PoolMinPerProtocol > 0 {
				cfg.PoolMinPerProtocol = saved.PoolMinPerProtocol
			}

			// 延迟配置
			if saved.MaxLatencyMs > 0 {
				cfg.MaxLatencyMs = saved.MaxLatencyMs
			}
			if saved.MaxLatencyEmergency > 0 {
				cfg.MaxLatencyEmergency = saved.MaxLatencyEmergency
			}
			if saved.MaxLatencyHealthy > 0 {
				cfg.MaxLatencyHealthy = saved.MaxLatencyHealthy
			}

			// 验证配置
			if saved.ValidateConcurrency > 0 {
				cfg.ValidateConcurrency = saved.ValidateConcurrency
			}
			if saved.ValidateTimeout > 0 {
				cfg.ValidateTimeout = saved.ValidateTimeout
			}

			// 健康检查配置
			if saved.HealthCheckInterval > 0 {
				cfg.HealthCheckInterval = saved.HealthCheckInterval
			}
			if saved.HealthCheckBatchSize > 0 {
				cfg.HealthCheckBatchSize = saved.HealthCheckBatchSize
			}

			// 优化配置
			if saved.OptimizeInterval > 0 {
				cfg.OptimizeInterval = saved.OptimizeInterval
			}
			if saved.ReplaceThreshold > 0 && saved.ReplaceThreshold <= 1 {
				cfg.ReplaceThreshold = saved.ReplaceThreshold
			}

			// 兼容旧配置
			if saved.FetchInterval > 0 {
				cfg.FetchInterval = saved.FetchInterval
			}
			if saved.CheckInterval > 0 {
				cfg.CheckInterval = saved.CheckInterval
			}
		}
	}
	cfgMu.Lock()
	globalCfg = cfg
	cfgMu.Unlock()
	return cfg
}

// Get 获取当前配置
func Get() *Config {
	cfgMu.RLock()
	defer cfgMu.RUnlock()
	return globalCfg
}

// savedConfig 持久化可调整的字段
type savedConfig struct {
	// 池子配置
	PoolMaxSize        int     `json:"pool_max_size"`
	PoolHTTPRatio      float64 `json:"pool_http_ratio"`
	PoolMinPerProtocol int     `json:"pool_min_per_protocol"`

	// 延迟配置
	MaxLatencyMs        int `json:"max_latency_ms"`
	MaxLatencyEmergency int `json:"max_latency_emergency"`
	MaxLatencyHealthy   int `json:"max_latency_healthy"`

	// 验证配置
	ValidateConcurrency int `json:"validate_concurrency"`
	ValidateTimeout     int `json:"validate_timeout"`

	// 健康检查配置
	HealthCheckInterval  int `json:"health_check_interval"`
	HealthCheckBatchSize int `json:"health_check_batch_size"`

	// 优化配置
	OptimizeInterval int     `json:"optimize_interval"`
	ReplaceThreshold float64 `json:"replace_threshold"`

	// 兼容旧配置
	FetchInterval int `json:"fetch_interval,omitempty"`
	CheckInterval int `json:"check_interval,omitempty"`
}

// Save 保存配置到文件，并更新内存配置
func Save(cfg *Config) error {
	cfgMu.Lock()
	*globalCfg = *cfg
	cfgMu.Unlock()

	data, err := json.MarshalIndent(savedConfig{
		PoolMaxSize:          cfg.PoolMaxSize,
		PoolHTTPRatio:        cfg.PoolHTTPRatio,
		PoolMinPerProtocol:   cfg.PoolMinPerProtocol,
		MaxLatencyMs:         cfg.MaxLatencyMs,
		MaxLatencyEmergency:  cfg.MaxLatencyEmergency,
		MaxLatencyHealthy:    cfg.MaxLatencyHealthy,
		ValidateConcurrency:  cfg.ValidateConcurrency,
		ValidateTimeout:      cfg.ValidateTimeout,
		HealthCheckInterval:  cfg.HealthCheckInterval,
		HealthCheckBatchSize: cfg.HealthCheckBatchSize,
		OptimizeInterval:     cfg.OptimizeInterval,
		ReplaceThreshold:     cfg.ReplaceThreshold,
		FetchInterval:        cfg.FetchInterval,
		CheckInterval:        cfg.CheckInterval,
	}, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(ConfigFile(), data, 0644)
}

// CalculateSlots 根据配置计算各协议的槽位数
func (c *Config) CalculateSlots() (httpSlots, socks5Slots int) {
	httpSlots = int(float64(c.PoolMaxSize) * c.PoolHTTPRatio)
	socks5Slots = c.PoolMaxSize - httpSlots

	// 保证最小值
	if httpSlots < c.PoolMinPerProtocol {
		httpSlots = c.PoolMinPerProtocol
	}
	if socks5Slots < c.PoolMinPerProtocol {
		socks5Slots = c.PoolMinPerProtocol
	}

	return
}

// GetLatencyThreshold 根据池子状态返回合适的延迟阈值
func (c *Config) GetLatencyThreshold(poolStatus string) int {
	switch poolStatus {
	case "emergency":
		return c.MaxLatencyEmergency
	case "critical":
		return c.MaxLatencyEmergency
	case "warning":
		return c.MaxLatencyMs
	case "healthy":
		return c.MaxLatencyHealthy
	default:
		return c.MaxLatencyMs
	}
}
