"""模型清单路由:/v1/models、/v1/image_models、/v1/video_models(按用户档位过滤)。"""
from __future__ import annotations

from uuid import UUID

from fastapi import Depends

from ..model_gate import (
    default_image_variant,
    list_image_variants,
    list_video_variants,
    user_plan_role,
)


def register_model_routes(app, *, require_user) -> None:
    @app.get("/v1/models", tags=["misc"])
    def list_models(user_id: UUID = Depends(require_user)):
        """列出所有可用 LLM 模型(扫 config/models/*.yaml)。

        前端顶栏 / 新建对话框的模型下拉拉这个。is_default 标记 cfg["default_model"]
        命中项。开发期不缓存,每次扫一遍(几个文件 IO);改 YAML 立即生效。
        """
        from core.agent_builder import load_config
        from core.capabilities import ModelCapabilities
        from core.model_access import allowed_set
        from core.paths import ROOT
        import yaml as _yaml
        cfg = load_config()
        default = cfg["default_model"]
        models_dir = ROOT / cfg["models_dir"]
        # 按用户档位过滤:allowed=None → 全开(admin / '*' 档),否则只留集合内 profile。
        plan, role = user_plan_role(user_id)
        allowed = allowed_set(plan, role)

        out: list[dict] = []
        if models_dir.is_dir():
            for path in sorted(models_dir.glob("*.yaml")):
                try:
                    data = _yaml.safe_load(path.read_text(encoding="utf-8")) or {}
                except Exception:
                    continue
                family = data.get("family") or path.stem
                for variant in (data.get("variants") or {}).keys():
                    profile = f"{family}.{variant}"
                    if allowed is not None and profile not in allowed:
                        continue
                    try:
                        caps = ModelCapabilities.load(profile, models_dir)
                    except (ValueError, FileNotFoundError):
                        continue
                    out.append({
                        "profile": profile,
                        "display_name": caps.display_name or profile,
                        "family": caps.family,
                        "variant": caps.variant,
                        "thinking_enabled": caps.thinking_enabled,
                        "is_default": profile == default,
                    })
        return {"models": out}

    @app.get("/v1/image_models", tags=["misc"])
    def list_image_models(user_id: UUID = Depends(require_user)):
        """图像生成模型清单(扫 config/media/*.yaml image 段,跨 provider)。

        前端顶栏第二个下拉拉这个;空列表 → 没配 image variant 或本档无授权,UI 隐藏下拉。
        按用户档位过滤;`is_default` 见 default_image_variant(有 gpt_image 权限 →
        默认 GPT 生图,否则第一个)。开发期不缓存,改 YAML 立即生效。
        """
        from core.model_access import allowed_set
        plan, role = user_plan_role(user_id)
        allowed = allowed_set(plan, role)
        default_key = default_image_variant(allowed)
        out: list[dict] = []
        for key, cfg in list_image_variants():
            if allowed is not None and key not in allowed:
                continue
            out.append({
                "variant": key,
                "display_name": cfg.get("display_name") or key,
                "model_id": cfg.get("model_id") or "",
                "price_cny_per_image": cfg.get("price_cny_per_image"),
                "is_default": key == default_key,
            })
        return {"models": out}

    @app.get("/v1/video_models", tags=["misc"])
    def list_video_models(user_id: UUID = Depends(require_user)):
        """视频生成模型清单(扫 config/media/doubao.yaml video 段)。

        与 /v1/image_models 同范式;空列表 → UI 隐藏第三下拉。展示信息包括默认分辨率
        与 token 单价(¥/Mtok 文生视频路径),方便用户在下拉选项里直接看到 cost 量级。
        按用户档位过滤;`is_default` 标过滤后第一个 variant。
        """
        from core.model_access import allowed_set
        plan, role = user_plan_role(user_id)
        allowed = allowed_set(plan, role)
        out: list[dict] = []
        for key, cfg in list_video_variants():
            if allowed is not None and key not in allowed:
                continue
            out.append({
                "variant": key,
                "display_name": cfg.get("display_name") or key,
                "model_id": cfg.get("model_id") or "",
                "default_resolution": cfg.get("default_resolution"),
                "default_duration": cfg.get("default_duration"),
                "default_ratio": cfg.get("default_ratio"),
                "price_cny_per_mtoken_text2video": cfg.get("price_cny_per_mtoken_text2video"),
                "price_cny_per_mtoken_video2video": cfg.get("price_cny_per_mtoken_video2video"),
                "is_default": not out,  # 过滤后第一个
            })
        return {"models": out}
