"""
插件加载器
在 FastAPI lifespan startup 时扫描 app/plugins/* 并调用 init_plugin(app)

使用方式（main.py lifespan）：
    from app.core.services.plugin_loader import load_plugins
    await load_plugins(app)

禁用插件：在 .env 中设置
    DISABLED_PLUGINS=auto_dispatch,seo_sitemap
"""
import importlib
import logging
import os
from pathlib import Path
from fastapi import FastAPI

logger = logging.getLogger(__name__)

PLUGIN_ROOT = Path(__file__).parent.parent.parent / "plugins"


def _disabled_plugins() -> set[str]:
    raw = os.environ.get("DISABLED_PLUGINS", "")
    return {name.strip() for name in raw.split(",") if name.strip()}


def _discover_plugins() -> list[tuple[str, Path]]:
    """返回 [(plugin_name, plugin_dir)]，已跳过 _ 前缀和 DISABLED_PLUGINS 中的插件"""
    if not PLUGIN_ROOT.exists():
        return []
    disabled = _disabled_plugins()
    return [
        (d.name, d)
        for d in PLUGIN_ROOT.iterdir()
        if d.is_dir() and not d.name.startswith("_") and d.name not in disabled
    ]


def _load_plugin_module(plugin_name: str):
    """尝试导入 plugins.<name> 模块（先找 init_plugin.py，再回退 __init__.py）"""
    for module_name in (f"app.plugins.{plugin_name}.init_plugin", f"app.plugins.{plugin_name}"):
        try:
            return importlib.import_module(module_name)
        except ImportError:
            continue
    return None


async def load_plugins(app: FastAPI) -> None:
    """
    扫描插件目录，挂载到 app
    加载失败不阻止主应用启动，只记录日志
    """
    plugins = _discover_plugins()
    if not plugins:
        logger.info("No plugins discovered in %s", PLUGIN_ROOT)
        return

    for plugin_name, plugin_dir in plugins:
        try:
            mod = _load_plugin_module(plugin_name)
            if mod is None:
                logger.warning("Plugin %s: no module found", plugin_name)
                continue

            if hasattr(mod, "init_plugin"):
                mod.init_plugin(app)
                logger.info("Loaded plugin: %s", plugin_name)
            else:
                logger.debug(
                    "Plugin %s: module %s has no init_plugin(), skipping",
                    plugin_name,
                    mod.__name__,
                )
        except Exception as exc:
            # 插件级别异常不影响主应用
            logger.error(
                "Plugin %s failed to load: %s",
                plugin_name,
                exc,
                exc_info=True,
            )
