package config

import (
	"fmt"
	"os"
	"path/filepath"
	"sync"

	"gopkg.in/yaml.v3"
)

type ServerConfig struct {
	WebPort int `yaml:"web_port"` // Gin Web服务器端口
	UDPPort int `yaml:"udp_port"` // UDP服务器端口
}

type DatabaseConfig struct {
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	DBName   string `yaml:"dbname"`
	SSLMode  string `yaml:"sslmode"`
}

// ForecastConfig 预报相关配置
type ForecastConfig struct {
	CaiyunToken string `yaml:"caiyun_token"`
}

// RadarConfig 雷达相关配置
type RadarConfig struct {
	// RealtimeIntervalMinutes 彩云实况拉取周期（分钟）。允许值：10、30、60。默认 10。
	RealtimeIntervalMinutes int `yaml:"realtime_interval_minutes"`
	// RealtimeEnabled 是否启用彩云实况定时任务。默认 false（不下载）。
	RealtimeEnabled bool `yaml:"realtime_enabled"`
	// Aliases 配置化的雷达别名列表（可用于前端选择与实况拉取）。
	Aliases []RadarAlias `yaml:"aliases"`
}

// RadarAlias 配置中的雷达别名条目
type RadarAlias struct {
	Alias string  `yaml:"alias"`
	Lat   float64 `yaml:"lat"`
	Lon   float64 `yaml:"lon"`
	Z     int     `yaml:"z"`
	Y     int     `yaml:"y"`
	X     int     `yaml:"x"`
}

// MySQLConfig MySQL 连接配置（用于 rtk_data）
type MySQLConfig struct {
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	DBName   string `yaml:"dbname"`
	Params   string `yaml:"params"` // 例如: parseTime=true&loc=Asia%2FShanghai
}

type Config struct {
	Server   ServerConfig   `yaml:"server"`
	Database DatabaseConfig `yaml:"database"`
	Forecast ForecastConfig `yaml:"forecast"`
	Radar    RadarConfig    `yaml:"radar"`
	MySQL    MySQLConfig    `yaml:"mysql"`
}

var (
	instance *Config
	once     sync.Once
)

// GetConfig 返回配置单例
func GetConfig() *Config {
	once.Do(func() {
		instance = &Config{}
		if err := instance.loadConfig(); err != nil {
			panic(fmt.Sprintf("加载配置文件失败: %v", err))
		}
	})
	return instance
}

// loadConfig 从配置文件加载配置
func (c *Config) loadConfig() error {
	// 尝试多个位置查找配置文件（兼容从仓库根目录、bin目录、系统安装路径运行）
	exePath, _ := os.Executable()
	exeDir := ""
	if exePath != "" {
		exeDir = filepath.Dir(exePath)
	}
	// 优先顺序：可执行文件所在目录，其次其父目录；然后回退到工作目录及上级，再到系统级/用户级
	configPaths := []string{
		// 可执行文件所在目录优先
		filepath.Join(exeDir, "config.yaml"),
		filepath.Join(exeDir, "..", "config.yaml"),
		// 工作目录及其上级
		"config.yaml",
		"../config.yaml",
		"../../config.yaml",
		// 系统级与用户级
		"/etc/weatherstation/config.yaml",
		filepath.Join(os.Getenv("HOME"), ".weatherstation", "config.yaml"),
	}

	var data []byte
	var err error
	for _, path := range configPaths {
		if data, err = os.ReadFile(path); err == nil {
			break
		}
	}
	if err != nil {
		return fmt.Errorf("未找到配置文件: %v", err)
	}

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

	return c.validate()
}

// validate 验证配置有效性
func (c *Config) validate() error {
	if c.Server.WebPort <= 0 {
		c.Server.WebPort = 10003 // 默认Web端口
	}
	if c.Server.UDPPort <= 0 {
		c.Server.UDPPort = 10001 // 默认UDP端口
	}
	if c.Database.SSLMode == "" {
		c.Database.SSLMode = "disable" // 默认禁用SSL
	}
	if c.MySQL.Port <= 0 {
		c.MySQL.Port = 3306
	}
	// Radar 默认拉取周期
	if c.Radar.RealtimeIntervalMinutes != 10 && c.Radar.RealtimeIntervalMinutes != 30 && c.Radar.RealtimeIntervalMinutes != 60 {
		c.Radar.RealtimeIntervalMinutes = 10
	}
	// 默认关闭实时抓取（可按需开启）
	// 若用户已有旧配置未设置该字段，默认为 false
	// CaiyunToken 允许为空：表示不启用彩云定时任务
	return nil
}
