"""同步配置管理模块。

该模块提供统一的同步配置管理，支持：
- 默认的线程数和速率限制配置
- 每个接口单独的速率限制配置
- 从 JSON 配置文件加载配置

配置文件路径: config/sync_config.json

配置示例:
    {
        "default": {
            "threads": 10,
            "rate_limit": 300
        },
        "interfaces": {
            "pro_bar": {
                "rate_limit": 200
            },
            "daily_basic": {
                "rate_limit": 150
            },
            "income": {
                "rate_limit": 100
            }
        }
    }
"""

import json
import threading
from dataclasses import dataclass, field, asdict
from pathlib import Path
from typing import Optional, Dict, Any
from functools import lru_cache


@dataclass
class InterfaceConfig:
    """单个接口的配置。"""

    rate_limit: Optional[int] = None
    threads: Optional[int] = None


@dataclass
class SyncConfig:
    """同步配置类。"""

    default: InterfaceConfig = field(
        default_factory=lambda: InterfaceConfig(
            rate_limit=300,
            threads=10,
        )
    )
    interfaces: Dict[str, InterfaceConfig] = field(default_factory=dict)

    def get_interface_config(self, interface_name: str) -> InterfaceConfig:
        """获取指定接口的配置。

        如果接口有特定配置则返回，否则返回默认配置。

        Args:
            interface_name: 接口名称

        Returns:
            接口配置对象
        """
        if interface_name in self.interfaces:
            interface_config = self.interfaces[interface_name]
            # 合并默认值（特定配置覆盖默认）
            return InterfaceConfig(
                rate_limit=interface_config.rate_limit
                if interface_config.rate_limit is not None
                else self.default.rate_limit,
                threads=interface_config.threads
                if interface_config.threads is not None
                else self.default.threads,
            )
        return self.default

    def get_rate_limit(self, interface_name: str) -> int:
        """获取指定接口的速率限制。

        Args:
            interface_name: 接口名称

        Returns:
            每分钟请求数
        """
        config = self.get_interface_config(interface_name)
        return config.rate_limit or self.default.rate_limit or 300

    def get_threads(self, interface_name: str) -> int:
        """获取指定接口的线程数。

        Args:
            interface_name: 接口名称

        Returns:
            线程数
        """
        config = self.get_interface_config(interface_name)
        return config.threads or self.default.threads or 10

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式。"""
        return {
            "default": {
                "rate_limit": self.default.rate_limit,
                "threads": self.default.threads,
            },
            "interfaces": {
                name: {
                    "rate_limit": config.rate_limit,
                    "threads": config.threads,
                }
                for name, config in self.interfaces.items()
            },
        }


class SyncConfigManager:
    """同步配置管理器。

    负责加载、保存和管理同步配置。
    支持从 JSON 文件加载配置，提供线程安全的单例访问。
    """

    _instance: Optional["SyncConfigManager"] = None
    _lock = threading.Lock()

    DEFAULT_CONFIG = {
        "default": {
            "threads": 10,
            "rate_limit": 300,
        },
        "interfaces": {
            # 高频接口（每秒可请求多次）
            "trade_cal": {"rate_limit": 500},
            "stock_basic": {"rate_limit": 500},
            "bak_basic": {"rate_limit": 200},
            "stock_st": {"rate_limit": 200},
            "stk_limit": {"rate_limit": 200},
            "cyq_perf": {"rate_limit": 150},
            "moneyflow": {"rate_limit": 150},
            "daily_basic": {"rate_limit": 150},
            "pro_bar": {"rate_limit": 200},
            # 低频财务接口
            "income": {"rate_limit": 100},
            "balance": {"rate_limit": 100},
            "cashflow": {"rate_limit": 100},
            "fina_indicator": {"rate_limit": 100},
            "namechange": {"rate_limit": 200},
        },
    }

    def __new__(cls, config_path: Optional[str] = None) -> "SyncConfigManager":
        """单例模式确保全局只有一个配置管理器实例。"""
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
                    cls._instance._initialized = False
        return cls._instance

    def __init__(self, config_path: Optional[str] = None):
        """初始化配置管理器。

        Args:
            config_path: 配置文件路径，默认使用项目根目录下的 config/sync_config.json
        """
        # 避免重复初始化
        if self._initialized:
            return

        if config_path is None:
            # 默认路径：项目根目录/config/sync_config.json
            project_root = Path(__file__).parent.parent.parent
            self.config_path = project_root / "config" / "sync_config.json"
        else:
            self.config_path = Path(config_path)

        self._config: Optional[SyncConfig] = None
        self._config_lock = threading.RLock()
        self._initialized = True

    def _load_config(self) -> SyncConfig:
        """从文件加载配置。

        如果配置文件不存在，则创建默认配置。

        Returns:
            同步配置对象
        """
        with self._config_lock:
            if self._config is not None:
                return self._config

            if self.config_path.exists():
                try:
                    with open(self.config_path, "r", encoding="utf-8") as f:
                        data = json.load(f)

                    default_data = data.get("default", {})
                    default_config = InterfaceConfig(
                        rate_limit=default_data.get("rate_limit", 300),
                        threads=default_data.get("threads", 10),
                    )

                    interfaces = {}
                    for name, config_data in data.get("interfaces", {}).items():
                        interfaces[name] = InterfaceConfig(
                            rate_limit=config_data.get("rate_limit"),
                            threads=config_data.get("threads"),
                        )

                    self._config = SyncConfig(
                        default=default_config,
                        interfaces=interfaces,
                    )
                    print(f"[SyncConfig] Loaded config from {self.config_path}")
                except Exception as e:
                    print(f"[SyncConfig] Error loading config: {e}, using defaults")
                    self._config = self._create_default_config()
            else:
                self._config = self._create_default_config()
                self.save_config()

            return self._config

    def _create_default_config(self) -> SyncConfig:
        """创建默认配置。"""
        default = InterfaceConfig(
            rate_limit=self.DEFAULT_CONFIG["default"]["rate_limit"],
            threads=self.DEFAULT_CONFIG["default"]["threads"],
        )

        interfaces = {}
        for name, config_data in self.DEFAULT_CONFIG["interfaces"].items():
            interfaces[name] = InterfaceConfig(
                rate_limit=config_data.get("rate_limit"),
                threads=config_data.get("threads"),
            )

        return SyncConfig(default=default, interfaces=interfaces)

    def save_config(self) -> None:
        """保存当前配置到文件。"""
        with self._config_lock:
            if self._config is None:
                self._config = self._create_default_config()

            try:
                self.config_path.parent.mkdir(parents=True, exist_ok=True)
                with open(self.config_path, "w", encoding="utf-8") as f:
                    json.dump(self._config.to_dict(), f, indent=2, ensure_ascii=False)
                print(f"[SyncConfig] Saved config to {self.config_path}")
            except Exception as e:
                print(f"[SyncConfig] Error saving config: {e}")

    def get_config(self) -> SyncConfig:
        """获取当前配置。

        Returns:
            同步配置对象
        """
        with self._config_lock:
            if self._config is None:
                return self._load_config()
            return self._config

    def get_rate_limit(self, interface_name: str) -> int:
        """获取指定接口的速率限制。

        Args:
            interface_name: 接口名称

        Returns:
            每分钟请求数
        """
        return self.get_config().get_rate_limit(interface_name)

    def get_threads(self, interface_name: str) -> int:
        """获取指定接口的线程数。

        Args:
            interface_name: 接口名称

        Returns:
            线程数
        """
        return self.get_config().get_threads(interface_name)

    def update_interface_config(
        self,
        interface_name: str,
        rate_limit: Optional[int] = None,
        threads: Optional[int] = None,
    ) -> None:
        """更新指定接口的配置。

        Args:
            interface_name: 接口名称
            rate_limit: 新的速率限制（None 表示不修改）
            threads: 新的线程数（None 表示不修改）
        """
        with self._config_lock:
            config = self.get_config()

            if interface_name not in config.interfaces:
                config.interfaces[interface_name] = InterfaceConfig()

            interface_config = config.interfaces[interface_name]
            if rate_limit is not None:
                interface_config.rate_limit = rate_limit
            if threads is not None:
                interface_config.threads = threads

            self.save_config()

    def reset_to_defaults(self) -> None:
        """重置为默认配置。"""
        with self._config_lock:
            self._config = self._create_default_config()
            self.save_config()
            print("[SyncConfig] Reset to default configuration")

    def list_interfaces(self) -> Dict[str, Dict[str, Any]]:
        """列出所有接口的配置。

        Returns:
            接口配置字典 {接口名: {rate_limit, threads}}
        """
        config = self.get_config()
        result = {}

        # 添加默认配置
        result["__default__"] = {
            "rate_limit": config.default.rate_limit,
            "threads": config.default.threads,
        }

        # 添加各接口配置
        all_interfaces = set(config.interfaces.keys()) | set(
            self.DEFAULT_CONFIG["interfaces"].keys()
        )
        for name in sorted(all_interfaces):
            iface_config = config.get_interface_config(name)
            result[name] = {
                "rate_limit": iface_config.rate_limit,
                "threads": iface_config.threads,
            }

        return result


# 全局配置管理器实例
_config_manager: Optional[SyncConfigManager] = None
_config_manager_lock = threading.Lock()


def get_sync_config_manager() -> SyncConfigManager:
    """获取同步配置管理器单例。

    Returns:
        SyncConfigManager 实例
    """
    global _config_manager
    if _config_manager is None:
        with _config_manager_lock:
            if _config_manager is None:
                _config_manager = SyncConfigManager()
    return _config_manager


def get_sync_config() -> SyncConfig:
    """获取同步配置。

    Returns:
        SyncConfig 实例
    """
    return get_sync_config_manager().get_config()


def get_rate_limit(interface_name: str) -> int:
    """获取指定接口的速率限制。

    Args:
        interface_name: 接口名称

    Returns:
        每分钟请求数
    """
    return get_sync_config_manager().get_rate_limit(interface_name)


def get_threads(interface_name: str) -> int:
    """获取指定接口的线程数。

    Args:
        interface_name: 接口名称

    Returns:
        线程数
    """
    return get_sync_config_manager().get_threads(interface_name)


def print_sync_config() -> None:
    """打印当前同步配置（用于调试）。"""
    manager = get_sync_config_manager()
    configs = manager.list_interfaces()

    print("\n" + "=" * 60)
    print("[SyncConfig] Current Configuration")
    print("=" * 60)

    default_config = configs.pop("__default__", {})
    print(
        f"Default: rate_limit={default_config.get('rate_limit')}/min, threads={default_config.get('threads')}"
    )
    print("-" * 60)

    for name, config in sorted(configs.items()):
        marker = "*" if name in manager.DEFAULT_CONFIG["interfaces"] else " "
        print(
            f"  [{marker}] {name:20s}: rate_limit={config['rate_limit']:3d}/min, threads={config['threads']:2d}"
        )

    print("=" * 60)
