package config

import (
	"fmt"
	"os"
	"time"

	"gopkg.in/yaml.v3"
)

// Config 全局配置根结构
type Config struct {
	Global      GlobalConfig      `yaml:"global"`
	MySQL       MySQLConfig       `yaml:"mysql"`
	Elasticsearch ESConfig        `yaml:"elasticsearch"`
	LDAP        LDAPConfig        `yaml:"ldap"`
	Switches    SwitchConfig      `yaml:"switches"`
	CloudDesktop CloudDesktopConfig `yaml:"cloud_desktop"`
	ADSecurity  ADSecurityConfig  `yaml:"ad_security"`
	Alert       AlertConfig       `yaml:"alert"`
}

// GlobalConfig 全局参数
type GlobalConfig struct {
	MaxConcurrency int           `yaml:"max_concurrency"` // 最大并发连接数
	Timeout        time.Duration `yaml:"timeout"`         // 全局超时
	LogLevel       string        `yaml:"log_level"`       // 日志级别: debug/info/warn/error
}

// MySQLConfig MySQL 数据库配置
type MySQLConfig struct {
	Host         string `yaml:"host"`
	Port         int    `yaml:"port"`
	Username     string `yaml:"username"`
	Password     string `yaml:"password"`
	Database     string `yaml:"database"`
	MaxOpenConns int    `yaml:"max_open_conns"`
	MaxIdleConns int    `yaml:"max_idle_conns"`
}

// ESConfig Elasticsearch 配置
type ESConfig struct {
	Hosts      []string `yaml:"hosts"`
	Username   string   `yaml:"username"`
	Password   string   `yaml:"password"`
	Index      string   `yaml:"index"`       // 索引模式，如 "logstash-*"
	TimeRange  string   `yaml:"time_range"`   // 检索时间范围，如 "15m"
	MinLevel   string   `yaml:"min_level"`    // 最低日志级别，如 "ERROR"
}

// LDAPConfig AD 域 LDAP 配置
type LDAPConfig struct {
	Host       string `yaml:"host"`
	Port       int    `yaml:"port"`
	BindDN     string `yaml:"bind_dn"`      // 绑定 DN，如 cn=admin,dc=example,dc=com
	Password   string `yaml:"password"`
	BaseDN     string `yaml:"base_dn"`      // 搜索基础 DN，如 dc=example,dc=com
	UseTLS     bool   `yaml:"use_tls"`
	SkipVerify bool   `yaml:"skip_verify"`  // 跳过证书验证
}

// SwitchConfig 交换机巡检配置
type SwitchConfig struct {
	Devices []SwitchDevice `yaml:"devices"`
	// 巡检命令模板，{hostname} 等占位符将在运行时替换
	Commands []string `yaml:"commands"`
	// 阈值
	CPUThreshold     float64 `yaml:"cpu_threshold"`      // CPU 使用率阈值 (%)
	MemoryThreshold  float64 `yaml:"memory_threshold"`   // 内存使用率阈值 (%)
	InterfaceErrorThreshold int `yaml:"interface_error_threshold"` // 接口错误包阈值
}

// SwitchDevice 交换机设备定义
type SwitchDevice struct {
	Name     string `yaml:"name"`
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
	Enable   string `yaml:"enable"` // enable 密码（Cisco）
	Type     string `yaml:"type"`   // 设备类型: cisco/h3c/huawei
}

// CloudDesktopConfig 云桌面巡检配置
type CloudDesktopConfig struct {
	APIHost      string  `yaml:"api_host"`       // 云桌面管理平台 API 地址
	APIKey       string  `yaml:"api_key"`        // API 密钥
	CPUThreshold float64 `yaml:"cpu_threshold"`  // CPU 使用率阈值 (%)
	MemThreshold float64 `yaml:"mem_threshold"`  // 内存使用率阈值 (%)
	DiskThreshold float64 `yaml:"disk_threshold"` // 磁盘使用率阈值 (%)
	IOPSThreshold int    `yaml:"iops_threshold"`  // IOPS 阈值
}

// ADSecurityConfig AD 域安全扫描配置
type ADSecurityConfig struct {
	PasswordMaxAge      int      `yaml:"password_max_age"`      // 密码最大使用天数
	DisabledAccountOnly bool     `yaml:"disabled_account_only"` // 仅检查禁用账户
	PrivilegedGroups    []string `yaml:"privileged_groups"`     // 特权组列表
	CheckLockedAccounts bool     `yaml:"check_locked_accounts"` // 检查锁定账户
	CheckPasswordNeverExpires bool `yaml:"check_password_never_expires"` // 检查密码永不过期
}

// AlertConfig 企业微信告警配置
type AlertConfig struct {
	WebhookURL  string `yaml:"webhook_url"`   // 企业微信机器人 Webhook
	Enabled     bool   `yaml:"enabled"`       // 是否启用告警
	DedupWindow time.Duration `yaml:"dedup_window"` // 去重时间窗口
}

// Load 从 YAML 文件加载配置
func Load(path string) (*Config, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %w", err)
	}

	var cfg Config
	if err := yaml.Unmarshal(data, &cfg); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %w", err)
	}

	// 设置默认值
	cfg.setDefaults()

	return &cfg, nil
}

// setDefaults 设置配置默认值
func (c *Config) setDefaults() {
	if c.Global.MaxConcurrency <= 0 {
		c.Global.MaxConcurrency = 10
	}
	if c.Global.Timeout <= 0 {
		c.Global.Timeout = 30 * time.Second
	}
	if c.Global.LogLevel == "" {
		c.Global.LogLevel = "info"
	}
	if c.MySQL.Port == 0 {
		c.MySQL.Port = 3306
	}
	if c.MySQL.MaxOpenConns <= 0 {
		c.MySQL.MaxOpenConns = 20
	}
	if c.MySQL.MaxIdleConns <= 0 {
		c.MySQL.MaxIdleConns = 5
	}
	if c.LDAP.Port == 0 {
		c.LDAP.Port = 389
	}
	if c.Switches.CPUThreshold <= 0 {
		c.Switches.CPUThreshold = 80.0
	}
	if c.Switches.MemoryThreshold <= 0 {
		c.Switches.MemoryThreshold = 80.0
	}
	if c.Switches.InterfaceErrorThreshold <= 0 {
		c.Switches.InterfaceErrorThreshold = 100
	}
	if c.CloudDesktop.CPUThreshold <= 0 {
		c.CloudDesktop.CPUThreshold = 80.0
	}
	if c.CloudDesktop.MemThreshold <= 0 {
		c.CloudDesktop.MemThreshold = 85.0
	}
	if c.CloudDesktop.DiskThreshold <= 0 {
		c.CloudDesktop.DiskThreshold = 90.0
	}
	if c.CloudDesktop.IOPSThreshold <= 0 {
		c.CloudDesktop.IOPSThreshold = 5000
	}
	if c.ADSecurity.PasswordMaxAge <= 0 {
		c.ADSecurity.PasswordMaxAge = 90
	}
	if c.Alert.DedupWindow <= 0 {
		c.Alert.DedupWindow = 30 * time.Minute
	}
	if c.Elasticsearch.TimeRange == "" {
		c.Elasticsearch.TimeRange = "15m"
	}
	if c.Elasticsearch.MinLevel == "" {
		c.Elasticsearch.MinLevel = "ERROR"
	}
}

// DSN 返回 MySQL 连接 DSN
func (c *MySQLConfig) DSN() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&loc=Local",
		c.Username, c.Password, c.Host, c.Port, c.Database)
}
