"""
配置管理
统一从项目根目录的 .env 文件加载配置
"""

import os
from dotenv import load_dotenv

# 加载项目根目录的 .env 文件
# 路径: MiroFish/.env (相对于 backend/app/config.py)
project_root_env = os.path.join(os.path.dirname(__file__), '../../.env')

if os.path.exists(project_root_env):
    load_dotenv(project_root_env, override=True)
else:
    # 如果根目录没有 .env，尝试加载环境变量（用于生产环境）
    load_dotenv(override=True)


def _resolve_llm_config() -> tuple[str, str, str | None]:
    """
    解析LLM配置。

    优先级：
      1. 如果设置了 LLM_PROVIDER，使用提供商预设填充 base_url 和 model（但可被显式值覆盖）
      2. 否则使用 LLM_BASE_URL / LLM_MODEL_NAME（兼容原有行为）

    Returns:
        (base_url, model_name, provider_name_or_none)
    """
    from .providers import get_provider

    provider_name = os.environ.get('LLM_PROVIDER', '').strip()
    explicit_base_url = os.environ.get('LLM_BASE_URL', '').strip()
    explicit_model = os.environ.get('LLM_MODEL_NAME', '').strip()

    if provider_name:
        preset = get_provider(provider_name)
        if preset is None:
            provider_names = ["openai", "deepseek", "xiaomi_mimo", "alibaba_dashscope", "minimax"]
            available = ", ".join(provider_names)
            raise ValueError(
                f"未知的 LLM_PROVIDER: '{provider_name}'. "
                f"可用值: {available}"
            )
        # 显式值优先于预设默认值
        base_url = explicit_base_url or preset.base_url
        model = explicit_model or preset.default_model
        return base_url, model, provider_name
    else:
        # 兼容原有行为：无 LLM_PROVIDER 时直接使用显式值
        base_url = explicit_base_url or 'https://api.openai.com/v1'
        model = explicit_model or 'gpt-4o-mini'
        return base_url, model, None


# 在模块加载时解析配置（避免重复计算）
_llm_base_url, _llm_model_name, _llm_provider = _resolve_llm_config()


class Config:
    """Flask配置类"""
    
    # Flask配置
    SECRET_KEY = os.environ.get('SECRET_KEY', 'mirofish-secret-key')
    DEBUG = os.environ.get('FLASK_DEBUG', 'True').lower() == 'true'
    
    # JSON配置 - 禁用ASCII转义，让中文直接显示（而不是 \uXXXX 格式）
    JSON_AS_ASCII = False
    
    # LLM配置（统一使用OpenAI格式）
    LLM_API_KEY = os.environ.get('LLM_API_KEY')
    LLM_PROVIDER = _llm_provider          # e.g. "deepseek" or None
    LLM_BASE_URL = _llm_base_url
    LLM_MODEL_NAME = _llm_model_name
    
    # Zep配置
    ZEP_API_KEY = os.environ.get('ZEP_API_KEY')
    
    # 文件上传配置
    MAX_CONTENT_LENGTH = 50 * 1024 * 1024  # 50MB
    UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), '../uploads')
    ALLOWED_EXTENSIONS = {'pdf', 'md', 'txt', 'markdown'}
    
    # 文本处理配置
    DEFAULT_CHUNK_SIZE = 500  # 默认切块大小
    DEFAULT_CHUNK_OVERLAP = 50  # 默认重叠大小
    
    # OASIS模拟配置
    OASIS_DEFAULT_MAX_ROUNDS = int(os.environ.get('OASIS_DEFAULT_MAX_ROUNDS', '10'))
    OASIS_SIMULATION_DATA_DIR = os.path.join(os.path.dirname(__file__), '../uploads/simulations')
    
    # OASIS平台可用动作配置
    OASIS_TWITTER_ACTIONS = [
        'CREATE_POST', 'LIKE_POST', 'REPOST', 'FOLLOW', 'DO_NOTHING', 'QUOTE_POST'
    ]
    OASIS_REDDIT_ACTIONS = [
        'LIKE_POST', 'DISLIKE_POST', 'CREATE_POST', 'CREATE_COMMENT',
        'LIKE_COMMENT', 'DISLIKE_COMMENT', 'SEARCH_POSTS', 'SEARCH_USER',
        'TREND', 'REFRESH', 'DO_NOTHING', 'FOLLOW', 'MUTE'
    ]
    
    # Report Agent配置
    REPORT_AGENT_MAX_TOOL_CALLS = int(os.environ.get('REPORT_AGENT_MAX_TOOL_CALLS', '5'))
    REPORT_AGENT_MAX_REFLECTION_ROUNDS = int(os.environ.get('REPORT_AGENT_MAX_REFLECTION_ROUNDS', '2'))
    REPORT_AGENT_TEMPERATURE = float(os.environ.get('REPORT_AGENT_TEMPERATURE', '0.5'))
    
    @classmethod
    def validate(cls) -> list[str]:
        """验证必要配置"""
        errors: list[str] = []
        if not cls.LLM_API_KEY:
            errors.append("LLM_API_KEY 未配置")
        if not cls.ZEP_API_KEY:
            errors.append("ZEP_API_KEY 未配置")
        return errors

    @classmethod
    def get_active_provider_info(cls) -> dict:
        """返回当前活跃的LLM提供商信息（用于日志/API展示）"""
        from .providers import get_provider

        info = {
            "provider": cls.LLM_PROVIDER or "custom",
            "base_url": cls.LLM_BASE_URL,
            "model": cls.LLM_MODEL_NAME,
        }
        if cls.LLM_PROVIDER:
            preset = get_provider(cls.LLM_PROVIDER)
            if preset:
                info["display_name"] = preset.display_name
                info["notes"] = preset.notes
        return info
