"""
统一配置管理 - 所有接口、配置、SQL入口的集中管理
"""

import os
import sqlite3
from pathlib import Path
from typing import Optional, Dict, Any
from dataclasses import dataclass
import logging

# 尝试加载环境变量
try:
    from dotenv import load_dotenv
    load_dotenv()
except Exception:
    # 如果没有.env文件或加载失败，使用默认配置
    pass

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


@dataclass
class DatabaseConfig:
    """数据库配置"""
    # 数据库路径
    database_path: str = "data/app.db"
    database_url: str = "sqlite:///./data/app.db"
    
    # 数据库连接参数
    connection_timeout: int = 30
    check_same_thread: bool = False
    
    # 表配置
    enable_foreign_keys: bool = True
    enable_wal_mode: bool = True


@dataclass
class APIConfig:
    """API接口配置"""
    # 千问大模型配置
    qwen_api_key: Optional[str] = None
    qwen_base_url: str = "https://dashscope.aliyuncs.com/compatible-mode/v1"
    qwen_model: str = "qwen-plus-latest"
    qwen_temperature: float = 0.7
    qwen_max_tokens: int = 2000
    
    # OpenAI配置（备用）
    openai_api_key: Optional[str] = None
    openai_model: str = "gpt-4"
    
    # Anthropic配置（备用）
    anthropic_api_key: Optional[str] = None
    anthropic_model: str = "claude-3-sonnet-20240229"
    
    # API超时配置
    api_timeout: int = 30
    api_retry_count: int = 3


@dataclass
class AppConfig:
    """应用配置"""
    # 应用基本信息
    app_name: str = "个性化饮食推荐助手"
    version: str = "1.0.0"
    debug: bool = True
    
    # 路径配置
    model_path: str = "models/"
    log_path: str = "logs/"
    data_path: str = "data/"
    user_data_path: str = "data/users/"
    training_data_path: str = "data/training/"
    
    # 日志配置
    log_level: str = "INFO"
    log_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    log_file: str = "logs/app.log"


@dataclass
class MLConfig:
    """机器学习配置"""
    # 推荐系统配置
    max_recommendations: int = 5
    min_training_samples: int = 10
    model_update_threshold: int = 50
    
    # 模型配置
    model_save_format: str = "joblib"
    enable_model_caching: bool = True
    model_cache_size: int = 100
    
    # 特征工程配置
    tfidf_max_features: int = 1000
    tfidf_ngram_range: tuple = (1, 2)
    similarity_threshold: float = 0.7


@dataclass
class OCRConfig:
    """OCR识别配置"""
    # OCR引擎配置
    # 默认只启用轻量级Tesseract，其他引擎需要额外安装深度学习框架
    enable_tesseract: bool = True  # 轻量级，推荐使用
    enable_paddleocr: bool = False  # 可选，需要PaddlePaddle，占用内存较大
    enable_easyocr: bool = False   # 可选，需要PyTorch，占用内存很大（1-2GB）
    
    # 识别参数
    min_confidence: float = 0.6
    max_processing_time: float = 30.0
    
    # 图片处理配置
    image_max_size: tuple = (1920, 1080)
    image_quality: int = 95
    enable_image_preprocessing: bool = True


@dataclass
class UIConfig:
    """界面配置"""
    # 移动端界面配置
    mobile_width: int = 375
    mobile_height: int = 812
    
    # 主题配置
    theme_mode: str = "light"  # light, dark, system
    color_theme: str = "blue"
    
    # 圆角配置
    corner_radius_small: int = 8
    corner_radius_medium: int = 12
    corner_radius_large: int = 15
    corner_radius_xlarge: int = 20
    corner_radius_xxlarge: int = 25


class UnifiedConfig:
    """统一配置管理类"""
    
    def __init__(self):
        self.database = DatabaseConfig()
        self.api = APIConfig()
        self.app = AppConfig()
        self.ml = MLConfig()
        self.ocr = OCRConfig()
        self.ui = UIConfig()
        
        # 从环境变量加载配置
        self._load_from_env()
        
        # 创建必要目录
        self._create_directories()
    
    def _load_from_env(self):
        """从环境变量加载配置"""
        # 数据库配置
        if os.getenv('DATABASE_PATH'):
            self.database.database_path = os.getenv('DATABASE_PATH')
        
        # API配置 - 使用统一API密钥管理
        from config.api_keys import get_api_key_manager
        api_manager = get_api_key_manager()
        
        self.api.qwen_api_key = api_manager.get_qwen_key()
        self.api.qwen_base_url = os.getenv('QWEN_BASE_URL', self.api.qwen_base_url)
        self.api.qwen_model = os.getenv('QWEN_MODEL', self.api.qwen_model)
        
        self.api.openai_api_key = api_manager.get_openai_key()
        self.api.anthropic_api_key = api_manager.get_anthropic_key()
        
        # 应用配置
        if os.getenv('DEBUG'):
            self.app.debug = os.getenv('DEBUG').lower() == 'true'
        
        if os.getenv('LOG_LEVEL'):
            self.app.log_level = os.getenv('LOG_LEVEL')
        
        # ML配置
        if os.getenv('MAX_RECOMMENDATIONS'):
            self.ml.max_recommendations = int(os.getenv('MAX_RECOMMENDATIONS'))
        
        if os.getenv('MIN_TRAINING_SAMPLES'):
            self.ml.min_training_samples = int(os.getenv('MIN_TRAINING_SAMPLES'))
    
    def _create_directories(self):
        """创建必要的目录"""
        directories = [
            self.app.data_path,
            self.app.user_data_path,
            self.app.training_data_path,
            self.app.model_path,
            self.app.log_path,
            Path(self.database.database_path).parent
        ]
        
        for directory in directories:
            Path(directory).mkdir(parents=True, exist_ok=True)
    
    def get_database_connection(self) -> sqlite3.Connection:
        """获取数据库连接"""
        try:
            conn = sqlite3.connect(
                self.database.database_path,
                timeout=self.database.connection_timeout,
                check_same_thread=self.database.check_same_thread
            )
            
            # 启用外键约束
            if self.database.enable_foreign_keys:
                conn.execute("PRAGMA foreign_keys = ON")
            
            # 启用WAL模式
            if self.database.enable_wal_mode:
                conn.execute("PRAGMA journal_mode = WAL")
            
            return conn
        except Exception as e:
            logger.error(f"数据库连接失败: {e}")
            raise
    
    def get_api_config(self, provider: str = "qwen") -> Dict[str, Any]:
        """获取API配置"""
        if provider == "qwen":
            return {
                "api_key": self.api.qwen_api_key,
                "base_url": self.api.qwen_base_url,
                "model": self.api.qwen_model,
                "temperature": self.api.qwen_temperature,
                "max_tokens": self.api.qwen_max_tokens,
                "timeout": self.api.api_timeout,
                "retry_count": self.api.api_retry_count
            }
        elif provider == "openai":
            return {
                "api_key": self.api.openai_api_key,
                "model": self.api.openai_model,
                "timeout": self.api.api_timeout,
                "retry_count": self.api.api_retry_count
            }
        elif provider == "anthropic":
            return {
                "api_key": self.api.anthropic_api_key,
                "model": self.api.anthropic_model,
                "timeout": self.api.api_timeout,
                "retry_count": self.api.api_retry_count
            }
        else:
            raise ValueError(f"不支持的API提供商: {provider}")
    
    def is_api_available(self, provider: str = "qwen") -> bool:
        """检查API是否可用"""
        if provider == "qwen":
            return self.api.qwen_api_key is not None
        elif provider == "openai":
            return self.api.openai_api_key is not None
        elif provider == "anthropic":
            return self.api.anthropic_api_key is not None
        else:
            return False
    
    def get_ocr_config(self) -> Dict[str, Any]:
        """获取OCR配置"""
        return {
            "enable_tesseract": self.ocr.enable_tesseract,
            "enable_paddleocr": self.ocr.enable_paddleocr,
            "enable_easyocr": self.ocr.enable_easyocr,
            "min_confidence": self.ocr.min_confidence,
            "max_processing_time": self.ocr.max_processing_time,
            "image_max_size": self.ocr.image_max_size,
            "image_quality": self.ocr.image_quality,
            "enable_preprocessing": self.ocr.enable_image_preprocessing
        }
    
    def get_ui_config(self) -> Dict[str, Any]:
        """获取界面配置"""
        return {
            "mobile_width": self.ui.mobile_width,
            "mobile_height": self.ui.mobile_height,
            "theme_mode": self.ui.theme_mode,
            "color_theme": self.ui.color_theme,
            "corner_radius": {
                "small": self.ui.corner_radius_small,
                "medium": self.ui.corner_radius_medium,
                "large": self.ui.corner_radius_large,
                "xlarge": self.ui.corner_radius_xlarge,
                "xxlarge": self.ui.corner_radius_xxlarge
            }
        }
    
    def validate_config(self) -> bool:
        """验证配置有效性"""
        try:
            # 检查数据库路径
            db_path = Path(self.database.database_path)
            if not db_path.parent.exists():
                db_path.parent.mkdir(parents=True, exist_ok=True)
            
            # 检查API配置
            if not self.is_api_available("qwen"):
                logger.warning("千问API密钥未配置，部分功能可能不可用")
            
            # 检查目录权限
            for directory in [self.app.data_path, self.app.model_path, self.app.log_path]:
                if not Path(directory).exists():
                    Path(directory).mkdir(parents=True, exist_ok=True)
            
            logger.info("配置验证通过")
            return True
            
        except Exception as e:
            logger.error(f"配置验证失败: {e}")
            return False
    
    def save_config_to_file(self, file_path: str = "config/app_config.json"):
        """保存配置到文件"""
        import json
        
        config_dict = {
            "database": self.database.__dict__,
            "api": self.api.__dict__,
            "app": self.app.__dict__,
            "ml": self.ml.__dict__,
            "ocr": self.ocr.__dict__,
            "ui": self.ui.__dict__
        }
        
        Path(file_path).parent.mkdir(parents=True, exist_ok=True)
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(config_dict, f, ensure_ascii=False, indent=2)
        
        logger.info(f"配置已保存到: {file_path}")
    
    def load_config_from_file(self, file_path: str = "config/app_config.json"):
        """从文件加载配置"""
        import json
        
        if not Path(file_path).exists():
            logger.warning(f"配置文件不存在: {file_path}")
            return False
        
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                config_dict = json.load(f)
            
            # 更新配置
            if "database" in config_dict:
                for key, value in config_dict["database"].items():
                    if hasattr(self.database, key):
                        setattr(self.database, key, value)
            
            if "api" in config_dict:
                for key, value in config_dict["api"].items():
                    if hasattr(self.api, key):
                        setattr(self.api, key, value)
            
            # 其他配置类似处理...
            
            logger.info(f"配置已从文件加载: {file_path}")
            return True
            
        except Exception as e:
            logger.error(f"加载配置文件失败: {e}")
            return False


# 全局配置实例
_config_instance: Optional[UnifiedConfig] = None


def get_config() -> UnifiedConfig:
    """获取全局配置实例"""
    global _config_instance
    if _config_instance is None:
        _config_instance = UnifiedConfig()
        _config_instance.validate_config()
    return _config_instance


def reload_config():
    """重新加载配置"""
    global _config_instance
    _config_instance = None
    return get_config()


# 便捷函数
def get_database_connection() -> sqlite3.Connection:
    """获取数据库连接"""
    return get_config().get_database_connection()


def get_api_config(provider: str = "qwen") -> Dict[str, Any]:
    """获取API配置"""
    return get_config().get_api_config(provider)


def is_api_available(provider: str = "qwen") -> bool:
    """检查API是否可用"""
    return get_config().is_api_available(provider)


if __name__ == "__main__":
    # 测试配置系统
    print("=== 统一配置管理测试 ===")
    
    config = get_config()
    
    print(f"✅ 应用名称: {config.app.app_name}")
    print(f"✅ 数据库路径: {config.database.database_path}")
    print(f"✅ 千问API可用: {config.is_api_available('qwen')}")
    print(f"✅ OpenAI API可用: {config.is_api_available('openai')}")
    
    # 测试数据库连接
    try:
        conn = config.get_database_connection()
        print("✅ 数据库连接成功")
        conn.close()
    except Exception as e:
        print(f"❌ 数据库连接失败: {e}")
    
    # 保存配置
    config.save_config_to_file()
    
    print("✅ 配置系统测试完成")
