"""
配置管理模块
提供优雅的配置文件管理功能
"""

import os
from pathlib import Path
from typing import Any, Dict, Optional, Union

import yaml
from sangreal_db import DataBase
from sqlalchemy import create_engine


class ConfigManager:
    """配置管理器

    提供统一的配置文件读取、验证和管理功能
    """

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

        Args:
            config_dir: 配置文件目录，默认为 ~/.sangreal/wind
        """
        self.config_dir = Path(config_dir) if config_dir else Path.home() / ".sangreal" / "wind"
        self.config_file = self.config_dir / "wind.yaml"
        self._config = None
        self._ensure_config_dir()

    def _ensure_config_dir(self) -> None:
        """确保配置目录存在"""
        if not self.config_dir.exists():
            self.config_dir.mkdir(parents=True, exist_ok=True)

    @property
    def config(self) -> Optional[Dict[str, Any]]:
        """获取配置内容"""
        if self._config is None:
            self._config = self._load_config()
        return self._config

    def _load_config(self) -> Optional[Dict[str, Any]]:
        """加载配置文件"""
        if not self.config_file.exists():
            return None

        try:
            with open(self.config_file, 'r', encoding='utf-8') as f:
                return yaml.load(f, Loader=yaml.FullLoader)
        except (yaml.YAMLError, IOError) as e:
            raise ValueError(f"Failed to load config file {self.config_file}: {e}")

    def get_section(self, section_name: str) -> Optional[Dict[str, Any]]:
        """获取配置文件的指定部分

        Args:
            section_name: 配置部分名称，如 'wind.config'

        Returns:
            配置字典，如果不存在则返回None
        """
        if self.config is None:
            return None

        return self.config.get(section_name)

    def get_database_config(self, section_name: str = "wind.config") -> Optional[Dict[str, str]]:
        """获取数据库配置

        Args:
            section_name: 配置部分名称

        Returns:
            包含engine和schema的配置字典
        """
        section = self.get_section(section_name)
        if section is None:
            return None

        return {
            'engine': section.get('engine'),
            'schema': section.get('schema', 'public')
        }

    def get_bundle_dir(self, section_name: str = "bundle.config") -> str:
        """获取bundle目录配置

        Args:
            section_name: 配置部分名称

        Returns:
            bundle目录路径
        """
        section = self.get_section(section_name)
        if section is None:
            return self._get_default_bundle_dir()

        bundle_dir = section.get('dir')
        if bundle_dir is None:
            return self._get_default_bundle_dir()

        return bundle_dir

    def _get_default_bundle_dir(self) -> str:
        """获取默认的bundle目录"""
        default_path = Path.home() / ".sangreal" / "backtest" / "bundle"
        default_path.mkdir(parents=True, exist_ok=True)
        return str(default_path) + os.sep

    def validate_bundle_dir(self, bundle_dir: str) -> None:
        """验证bundle目录配置

        Args:
            bundle_dir: bundle目录路径

        Raises:
            ValueError: 目录路径不以分隔符结尾
        """
        if not bundle_dir.endswith(os.sep):
            raise ValueError(f"bundle_dir路径必须以{os.sep}结尾")

    def ensure_bundle_dir(self, bundle_dir: str) -> None:
        """确保bundle目录存在

        Args:
            bundle_dir: bundle目录路径
        """
        bundle_path = Path(bundle_dir)
        if not bundle_path.exists():
            bundle_path.mkdir(parents=True, exist_ok=True)


class DatabaseManager:
    """数据库连接管理器

    提供数据库连接的创建、管理和缓存功能
    """

    def __init__(self, config_manager: ConfigManager):
        """初始化数据库管理器

        Args:
            config_manager: 配置管理器实例
        """
        self.config_manager = config_manager
        self._wind_db = None
        self._engine = None

    @property
    def wind_db(self) -> DataBase:
        """获取Wind数据库连接"""
        if self._wind_db is None:
            self._wind_db, self._engine = self._create_wind_db()
        return self._wind_db

    @property
    def engine(self):
        """获取SQLAlchemy引擎"""
        if self._engine is None:
            self._wind_db, self._engine = self._create_wind_db()
        return self._engine

    def _create_wind_db(self) -> tuple[DataBase, Any]:
        """创建Wind数据库连接"""
        db_config = self.config_manager.get_database_config()
        if db_config is None or db_config['engine'] is None:
            return DataBase(None), None

        engine = create_engine(db_config['engine'])
        schema = db_config['schema']
        return DataBase(engine, schema), engine


class BundleManager:
    """Bundle目录管理器

    提供bundle目录的配置和管理功能
    """

    def __init__(self, config_manager: ConfigManager):
        """初始化Bundle管理器

        Args:
            config_manager: 配置管理器实例
        """
        self.config_manager = config_manager
        self._bundle_dir = None

    @property
    def bundle_dir(self) -> str:
        """获取bundle目录路径"""
        if self._bundle_dir is None:
            self._bundle_dir = self._get_and_validate_bundle_dir()
        return self._bundle_dir

    def _get_and_validate_bundle_dir(self) -> str:
        """获取并验证bundle目录"""
        bundle_dir = self.config_manager.get_bundle_dir()
        self.config_manager.validate_bundle_dir(bundle_dir)
        self.config_manager.ensure_bundle_dir(bundle_dir)
        return bundle_dir


# 创建全局实例
_config_manager = ConfigManager()
_database_manager = DatabaseManager(_config_manager)
_bundle_manager = BundleManager(_config_manager)

# 导出向后兼容的全局变量
WIND_DB = _database_manager.wind_db
ENGINE = _database_manager.engine
BUNDLE_DIR = _bundle_manager.bundle_dir

# 导出管理器类以供高级用法
__all__ = [
    'ConfigManager',
    'DatabaseManager',
    'BundleManager',
    'WIND_DB',
    'ENGINE',
    'BUNDLE_DIR'
]