"""
系统配置

支持两种配置来源：
1. 环境变量 / .env 文件（传统方式，向后兼容）
2. 数据库 tenant_configs 表（新方式，支持热更新）

配置优先级：数据库 > 环境变量 > 默认值
"""

import os
import json
from functools import lru_cache
from typing import Optional, Any

from pydantic import Field, field_validator
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    """系统配置"""

    # 应用基础配置
    APP_NAME: str = "KaoPeiLian"
    APP_VERSION: str = "1.0.0"
    DEBUG: bool = Field(default=True)
    
    # 租户配置（用于多租户部署）
    TENANT_CODE: str = Field(default="demo", description="租户编码，如 hua, yy, hl")

    # 服务器配置
    HOST: str = Field(default="0.0.0.0")
    PORT: int = Field(default=8000)

    # 数据库配置
    DATABASE_URL: Optional[str] = Field(default=None)
    MYSQL_HOST: str = Field(default="localhost")
    MYSQL_PORT: int = Field(default=3306)
    MYSQL_USER: str = Field(default="root")
    MYSQL_PASSWORD: str = Field(default="password")
    MYSQL_DATABASE: str = Field(default="kaopeilian")
    
    @property
    def database_url(self) -> str:
        """构建数据库连接URL"""
        if self.DATABASE_URL:
            return self.DATABASE_URL
        
        # 使用urllib.parse.quote_plus来正确编码特殊字符
        import urllib.parse
        password = urllib.parse.quote_plus(self.MYSQL_PASSWORD)
        
        return f"mysql+aiomysql://{self.MYSQL_USER}:{password}@{self.MYSQL_HOST}:{self.MYSQL_PORT}/{self.MYSQL_DATABASE}?charset=utf8mb4"

    # Redis配置
    REDIS_URL: str = Field(default="redis://localhost:6379/0")

    # JWT配置
    SECRET_KEY: str = Field(default="your-secret-key-here")
    ALGORITHM: str = Field(default="HS256")
    ACCESS_TOKEN_EXPIRE_MINUTES: int = Field(default=30)
    REFRESH_TOKEN_EXPIRE_DAYS: int = Field(default=7)

    # 跨域配置
    CORS_ORIGINS: list[str] = Field(
        default=[
            "http://localhost:3000",
            "http://localhost:3001",
            "http://localhost:5173",
            "http://127.0.0.1:3000",
            "http://127.0.0.1:3001",
            "http://127.0.0.1:5173",
        ]
    )
    
    @field_validator('CORS_ORIGINS', mode='before')
    @classmethod
    def parse_cors_origins(cls, v):
        """解析 CORS_ORIGINS 环境变量（支持 JSON 格式字符串）"""
        if isinstance(v, str):
            try:
                return json.loads(v)
            except json.JSONDecodeError:
                # 如果不是 JSON 格式，尝试按逗号分割
                return [origin.strip() for origin in v.split(',')]
        return v

    # 日志配置
    LOG_LEVEL: str = Field(default="INFO")
    LOG_FORMAT: str = Field(default="text")  # text 或 json
    LOG_DIR: str = Field(default="logs")

    # 上传配置
    UPLOAD_DIR: str = Field(default="uploads")
    MAX_UPLOAD_SIZE: int = Field(default=15 * 1024 * 1024)  # 15MB
    
    @property
    def UPLOAD_PATH(self) -> str:
        """获取上传文件的完整路径"""
        import os
        return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), self.UPLOAD_DIR)

    # Coze 平台配置（陪练对话、播课等）
    COZE_API_BASE: Optional[str] = Field(default="https://api.coze.cn")
    COZE_WORKSPACE_ID: Optional[str] = Field(default=None)
    COZE_API_TOKEN: Optional[str] = Field(default="pat_Sa5OiuUl0gDflnKstQTToIz0sSMshBV06diX0owOeuI1ZK1xDLH5YZH9fSeuKLIi")
    COZE_TRAINING_BOT_ID: Optional[str] = Field(default=None)
    COZE_CHAT_BOT_ID: Optional[str] = Field(default=None)
    COZE_PRACTICE_BOT_ID: Optional[str] = Field(default="7560643598174683145")  # 陪练专用Bot ID
    # 播课工作流配置（多租户需在环境变量中覆盖，参见：应用配置清单.md）
    COZE_BROADCAST_WORKFLOW_ID: str = Field(default="7577983042284486666")  # 默认：演示版播课工作流
    COZE_BROADCAST_SPACE_ID: str = Field(default="7474971491470688296")  # 播课工作流空间ID
    COZE_BROADCAST_BOT_ID: Optional[str] = Field(default=None)  # 播课工作流专用Bot ID
    # OAuth配置（可选）
    COZE_OAUTH_CLIENT_ID: Optional[str] = Field(default=None)
    COZE_OAUTH_PUBLIC_KEY_ID: Optional[str] = Field(default=None)
    COZE_OAUTH_PRIVATE_KEY_PATH: Optional[str] = Field(default=None)
    
    # WebSocket语音配置
    COZE_WS_BASE_URL: str = Field(default="wss://ws.coze.cn")
    COZE_AUDIO_FORMAT: str = Field(default="pcm")  # 音频格式
    COZE_SAMPLE_RATE: int = Field(default=16000)  # 采样率（Hz）
    COZE_AUDIO_CHANNELS: int = Field(default=1)  # 声道数（单声道）
    COZE_AUDIO_BIT_DEPTH: int = Field(default=16)  # 位深度
    
    # 服务器公开访问域名
    PUBLIC_DOMAIN: str = Field(default="http://aiedu.ireborn.com.cn")
    
    # 言迹智能工牌API配置
    YANJI_API_BASE: str = Field(default="https://open.yanjiai.com")  # 正式环境
    YANJI_CLIENT_ID: str = Field(default="1Fld4LCWt2vpJNG5")
    YANJI_CLIENT_SECRET: str = Field(default="XE8w413qNtJBOdWc2aCezV0yMIHpUuTZ")
    YANJI_TENANT_ID: str = Field(default="516799409476866048")
    YANJI_ESTATE_ID: str = Field(default="516799468310364162")
    
    # SCRM 系统对接 API Key（用于内部服务间调用）
    SCRM_API_KEY: str = Field(default="scrm-kpl-api-key-2026-ruixiaomei")
    
    # AI 服务配置（知识点分析 V2 使用）
    # 首选服务商：4sapi.com（国内优化）
    AI_PRIMARY_API_KEY: str = Field(default="sk-9yMCXjRGANbacz20kJY8doSNy6Rf446aYwmgGIuIXQ7DAyBw")  # 测试阶段 Key
    AI_PRIMARY_BASE_URL: str = Field(default="https://4sapi.com/v1")
    # 备选服务商：OpenRouter（模型全，稳定性好）
    AI_FALLBACK_API_KEY: str = Field(default="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")  # 测试阶段 Key
    AI_FALLBACK_BASE_URL: str = Field(default="https://openrouter.ai/api/v1")
    # 默认模型
    AI_DEFAULT_MODEL: str = Field(default="gemini-3-flash-preview")
    # 请求超时（秒）
    AI_TIMEOUT: float = Field(default=120.0)

    model_config = {
        "env_file": ".env",
        "env_file_encoding": "utf-8",
        "case_sensitive": True,
        "extra": "allow",  # 允许额外的环境变量
    }


@lru_cache()
def get_settings() -> Settings:
    """获取系统配置（缓存）"""
    return Settings()


settings = get_settings()


# ============================================
# 动态配置获取（支持从数据库读取）
# ============================================

class DynamicConfig:
    """
    动态配置管理器
    
    用于在运行时从数据库获取配置，支持热更新。
    向后兼容：如果数据库不可用，回退到环境变量配置。
    """
    
    _tenant_loader = None
    _initialized = False
    
    @classmethod
    async def init(cls, redis_url: Optional[str] = None):
        """
        初始化动态配置管理器
        
        Args:
            redis_url: Redis URL（可选，用于缓存）
        """
        if cls._initialized:
            return
        
        try:
            from app.core.tenant_config import TenantConfigManager
            
            if redis_url:
                await TenantConfigManager.init_redis(redis_url)
            
            cls._initialized = True
        except Exception as e:
            import logging
            logging.getLogger(__name__).warning(f"动态配置初始化失败: {e}")
    
    @classmethod
    async def get(cls, key: str, default: Any = None, tenant_code: Optional[str] = None) -> Any:
        """
        获取配置值
        
        Args:
            key: 配置键（如 AI_PRIMARY_API_KEY）
            default: 默认值
            tenant_code: 租户编码（可选，默认使用环境变量中的 TENANT_CODE）
        
        Returns:
            配置值
        """
        # 确定租户编码
        if tenant_code is None:
            tenant_code = settings.TENANT_CODE
        
        # 配置键到分组的映射
        config_mapping = {
            # 数据库
            "MYSQL_HOST": ("database", "MYSQL_HOST"),
            "MYSQL_PORT": ("database", "MYSQL_PORT"),
            "MYSQL_USER": ("database", "MYSQL_USER"),
            "MYSQL_PASSWORD": ("database", "MYSQL_PASSWORD"),
            "MYSQL_DATABASE": ("database", "MYSQL_DATABASE"),
            # Redis
            "REDIS_HOST": ("redis", "REDIS_HOST"),
            "REDIS_PORT": ("redis", "REDIS_PORT"),
            "REDIS_DB": ("redis", "REDIS_DB"),
            # 安全
            "SECRET_KEY": ("security", "SECRET_KEY"),
            "CORS_ORIGINS": ("security", "CORS_ORIGINS"),
            # Coze
            "COZE_PRACTICE_BOT_ID": ("coze", "COZE_PRACTICE_BOT_ID"),
            "COZE_BROADCAST_WORKFLOW_ID": ("coze", "COZE_BROADCAST_WORKFLOW_ID"),
            "COZE_BROADCAST_SPACE_ID": ("coze", "COZE_BROADCAST_SPACE_ID"),
            "COZE_OAUTH_CLIENT_ID": ("coze", "COZE_OAUTH_CLIENT_ID"),
            "COZE_OAUTH_PUBLIC_KEY_ID": ("coze", "COZE_OAUTH_PUBLIC_KEY_ID"),
            # AI
            "AI_PRIMARY_API_KEY": ("ai", "AI_PRIMARY_API_KEY"),
            "AI_PRIMARY_BASE_URL": ("ai", "AI_PRIMARY_BASE_URL"),
            "AI_FALLBACK_API_KEY": ("ai", "AI_FALLBACK_API_KEY"),
            "AI_FALLBACK_BASE_URL": ("ai", "AI_FALLBACK_BASE_URL"),
            "AI_DEFAULT_MODEL": ("ai", "AI_DEFAULT_MODEL"),
            "AI_TIMEOUT": ("ai", "AI_TIMEOUT"),
            # 言迹
            "YANJI_CLIENT_ID": ("yanji", "YANJI_CLIENT_ID"),
            "YANJI_CLIENT_SECRET": ("yanji", "YANJI_CLIENT_SECRET"),
            "YANJI_TENANT_ID": ("yanji", "YANJI_TENANT_ID"),
            "YANJI_ESTATE_ID": ("yanji", "YANJI_ESTATE_ID"),
        }
        
        # 尝试从数据库获取
        if cls._initialized and key in config_mapping:
            try:
                from app.core.tenant_config import TenantConfigManager
                
                config_group, config_key = config_mapping[key]
                loader = TenantConfigManager.get_loader(tenant_code)
                value = await loader.get_config(config_group, config_key)
                
                if value is not None:
                    return value
            except Exception:
                pass
        
        # 回退到环境变量 / Settings
        env_value = getattr(settings, key, None)
        if env_value is not None:
            return env_value
        
        return default
    
    @classmethod
    async def is_feature_enabled(cls, feature_code: str, tenant_code: Optional[str] = None) -> bool:
        """
        检查功能是否启用
        
        Args:
            feature_code: 功能编码
            tenant_code: 租户编码
        
        Returns:
            是否启用
        """
        if tenant_code is None:
            tenant_code = settings.TENANT_CODE
        
        if cls._initialized:
            try:
                from app.core.tenant_config import TenantConfigManager
                
                loader = TenantConfigManager.get_loader(tenant_code)
                return await loader.is_feature_enabled(feature_code)
            except Exception:
                pass
        
        return True  # 默认启用
    
    @classmethod
    async def refresh_cache(cls, tenant_code: Optional[str] = None):
        """
        刷新配置缓存
        
        Args:
            tenant_code: 租户编码（为空则刷新所有）
        """
        if not cls._initialized:
            return
        
        try:
            from app.core.tenant_config import TenantConfigManager
            
            if tenant_code:
                await TenantConfigManager.refresh_tenant_cache(tenant_code)
            else:
                await TenantConfigManager.refresh_all_cache()
        except Exception:
            pass
