package config

import (
	"encoding/json"
	"os"
	"strconv"
	"strings"
	"sync"
)

// MailServiceConfig 邮箱服务配置
type MailServiceConfig struct {
	Name       string `yaml:"name" json:"name"`
	APIBase    string `yaml:"api_base" json:"api_base"`
	APIToken   string `yaml:"api_token" json:"api_token"`
	Domain     string `yaml:"domain" json:"domain"`
	EmailPath  string `yaml:"email_path,omitempty" json:"email_path,omitempty"`
	AddUserAPI string `yaml:"add_user_api,omitempty" json:"add_user_api,omitempty"`
}

// Config 应用配置 (实时从数据库读取)
type Config struct {
	// 服务器配置 (启动时固定)
	Port       int    `json:"port"`
	CorsOrigin string `json:"cors_origin"`

	// S2A 配置 (可实时更新)
	S2AApiBase  string `json:"s2a_api_base"`
	S2AAdminKey string `json:"s2a_admin_key"`

	// 入库配置 (可实时更新)
	Concurrency int   `json:"concurrency"`
	Priority    int   `json:"priority"`
	GroupIDs    []int `json:"group_ids"`
	ProxyID     *int  `json:"proxy_id"`

	// 代理配置 (可实时更新)
	ProxyEnabled bool   `json:"proxy_enabled"`
	DefaultProxy string `json:"default_proxy"`

	// 自动化配置
	AutoPauseOnExpired bool   `json:"auto_pause_on_expired"`
	AccountsPath       string `json:"accounts_path"`

	// 邮箱服务
	MailServices []MailServiceConfig `json:"mail_services"`
}

// GetProxy 获取代理地址（如果启用）
func (c *Config) GetProxy() string {
	if c.ProxyEnabled && c.DefaultProxy != "" {
		return c.DefaultProxy
	}
	return ""
}

// Account 账号结构 (保持 JSON 格式用于账号文件)
type Account struct {
	Email        string `json:"email,omitempty"`
	Account      string `json:"account,omitempty"`
	Password     string `json:"password"`
	Name         string `json:"name,omitempty"`
	AccessToken  string `json:"access_token,omitempty"`
	Token        string `json:"token,omitempty"`
	RefreshToken string `json:"refresh_token,omitempty"`
	CreatedAt    string `json:"created_at,omitempty"`
	Pooled       bool   `json:"pooled,omitempty"`
	PooledAt     string `json:"pooled_at,omitempty"`
	PoolID       int    `json:"pool_id,omitempty"`
	Used         bool   `json:"used,omitempty"`
	UsedAt       string `json:"used_at,omitempty"`
}

// GetEmail 获取邮箱
func (a *Account) GetEmail() string {
	if a.Email != "" {
		return a.Email
	}
	return a.Account
}

// GetAccessToken 获取 Token
func (a *Account) GetAccessToken() string {
	if a.AccessToken != "" {
		return a.AccessToken
	}
	return a.Token
}

// PoolingConfig 入库任务配置
type PoolingConfig struct {
	Concurrency     int    `json:"concurrency"`
	SerialAuthorize bool   `json:"serial_authorize"`
	BrowserType     string `json:"browser_type"`
	Headless        bool   `json:"headless"`
	Proxy           string `json:"proxy"`
}

// 全局配置实例
var (
	Global   *Config
	configMu sync.RWMutex
)

// ConfigDB 配置数据库接口
type ConfigDB interface {
	GetConfig(key string) (string, error)
	SetConfig(key, value string) error
	GetAllConfig() (map[string]string, error)
}

var configDB ConfigDB

// SetConfigDB 设置配置数据库
func SetConfigDB(db ConfigDB) {
	configDB = db
}

// InitFromDB 从数据库初始化配置
func InitFromDB() *Config {
	configMu.Lock()
	defer configMu.Unlock()

	cfg := &Config{
		Port:        8848,
		CorsOrigin:  "*",
		Concurrency: 2,
		Priority:    0,
	}

	if configDB == nil {
		Global = cfg
		return cfg
	}

	// 从数据库加载配置
	if v, _ := configDB.GetConfig("s2a_api_base"); v != "" {
		cfg.S2AApiBase = v
	}
	if v, _ := configDB.GetConfig("s2a_admin_key"); v != "" {
		cfg.S2AAdminKey = v
	}
	if v, _ := configDB.GetConfig("concurrency"); v != "" {
		if n, err := strconv.Atoi(v); err == nil {
			cfg.Concurrency = n
		}
	}
	if v, _ := configDB.GetConfig("priority"); v != "" {
		if n, err := strconv.Atoi(v); err == nil {
			cfg.Priority = n
		}
	}
	if v, _ := configDB.GetConfig("group_ids"); v != "" {
		var ids []int
		for _, s := range strings.Split(v, ",") {
			if n, err := strconv.Atoi(strings.TrimSpace(s)); err == nil {
				ids = append(ids, n)
			}
		}
		cfg.GroupIDs = ids
	}
	if v, _ := configDB.GetConfig("proxy_enabled"); v == "true" {
		cfg.ProxyEnabled = true
	}
	if v, _ := configDB.GetConfig("default_proxy"); v != "" {
		cfg.DefaultProxy = v
	}
	if v, _ := configDB.GetConfig("mail_services"); v != "" {
		var services []MailServiceConfig
		if err := json.Unmarshal([]byte(v), &services); err == nil {
			cfg.MailServices = services
		}
	}

	Global = cfg
	return cfg
}

// SaveToDB 保存配置到数据库
func SaveToDB() error {
	if configDB == nil || Global == nil {
		return nil
	}

	configMu.RLock()
	cfg := Global
	configMu.RUnlock()

	configDB.SetConfig("s2a_api_base", cfg.S2AApiBase)
	configDB.SetConfig("s2a_admin_key", cfg.S2AAdminKey)
	configDB.SetConfig("concurrency", strconv.Itoa(cfg.Concurrency))
	configDB.SetConfig("priority", strconv.Itoa(cfg.Priority))

	if len(cfg.GroupIDs) > 0 {
		var ids []string
		for _, id := range cfg.GroupIDs {
			ids = append(ids, strconv.Itoa(id))
		}
		configDB.SetConfig("group_ids", strings.Join(ids, ","))
	}

	configDB.SetConfig("proxy_enabled", strconv.FormatBool(cfg.ProxyEnabled))
	configDB.SetConfig("default_proxy", cfg.DefaultProxy)

	if len(cfg.MailServices) > 0 {
		data, _ := json.Marshal(cfg.MailServices)
		configDB.SetConfig("mail_services", string(data))
	}

	return nil
}

// Update 更新配置 (实时生效)
func Update(cfg *Config) error {
	configMu.Lock()
	Global = cfg
	configMu.Unlock()
	return SaveToDB()
}

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

// FindPath 查找配置文件路径 (兼容)
func FindPath() string {
	if envPath := os.Getenv("CONFIG_PATH"); envPath != "" {
		return envPath
	}
	return "data/config.yaml"
}

// Load 加载配置 (兼容旧代码，现在直接从数据库加载)
func Load(path string) (*Config, error) {
	return InitFromDB(), nil
}

// LoadAccounts 加载账号列表 (保持 JSON 格式)
func LoadAccounts(path string) ([]Account, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}

	var accounts []Account
	if err := json.Unmarshal(data, &accounts); err != nil {
		return nil, err
	}

	return accounts, nil
}

// SaveAccounts 保存账号列表 (保持 JSON 格式)
func SaveAccounts(path string, accounts []Account) error {
	data, err := json.MarshalIndent(accounts, "", "  ")
	if err != nil {
		return err
	}

	return os.WriteFile(path, data, 0644)
}
