"""Skills(列表/详情/删除用户 skill)与 Memory(只读全貌/单篇)路由。"""
from __future__ import annotations

from uuid import UUID

from fastapi import Depends, HTTPException


def register_skill_memory_routes(app, *, require_user) -> None:
    @app.get("/v1/skills", tags=["skills"])
    def list_skills(user_id: UUID = Depends(require_user)):
        """列出当前用户可用的 skill(内置 + 自己的),供新建 task 时下拉选择。

        每次请求现扫(内置 `skills/<name>/SKILL.md` + 用户 `.skills/<name>/SKILL.md`,
        稳态 ~3ms),加 / 改 / 删 skill 目录后无需重启即可在前端看到。
        `core/agent_builder.py::build_agent` 同样每次新建 SkillRegistry,所以 agent 内部
        `load_skill` 与 system prompt discovery 也是热的。源标 `source`(builtin/user)+
        `overrides_builtin`(用户 skill 覆盖了同名内置)。`load_errors` 列出用户 skill
        因 frontmatter 问题未加载的,供前端提示。
        """
        from core.agent_builder import build_skill_registry, load_config, resolve_workspace
        cfg = load_config()
        ws = resolve_workspace(None, cfg)
        reg = build_skill_registry(cfg, ws, user_id, docker=False)
        return {
            "skills": [
                {
                    "name": s.name,
                    "description": s.description,
                    "source": s.source,
                    "overrides_builtin": s.name in reg.user_overrides,
                }
                for s in reg.skills.values()
            ],
            "load_errors": [{"name": n, "reason": r} for n, r in reg.load_errors],
        }

    @app.get("/v1/skills/{name}", tags=["skills"])
    def get_skill(name: str, user_id: UUID = Depends(require_user)):
        """返回某 skill 的完整 SKILL.md 正文(供前端 modal 展开查看)。

        内置 + 用户两来源都可查;同名时按 user wins 取用户那份(与 agent 看到的一致)。
        """
        from core.agent_builder import build_skill_registry, load_config, resolve_workspace
        cfg = load_config()
        ws = resolve_workspace(None, cfg)
        reg = build_skill_registry(cfg, ws, user_id, docker=False)
        skill = reg.get(name)
        if skill is None:
            raise HTTPException(404, f"skill not found: {name!r}")
        try:
            content = skill.full_content()
        except OSError as e:
            raise HTTPException(500, f"读取 SKILL.md 失败: {e}")
        return {
            "name": skill.name,
            "source": skill.source,
            "overrides_builtin": skill.name in reg.user_overrides,
            "content": content,
        }

    @app.delete("/v1/skills/{name}", status_code=204, tags=["skills"])
    def delete_skill(name: str, user_id: UUID = Depends(require_user)):
        """删除当前用户的私有 skill(`.skills/<name>/` 整目录)。

        只能删 user 源 —— 内置 skill 不可删(404,等同"用户那里没有这个可删的")。
        `.skills` 在文件面板隐藏,这是 UI 上删除自己 skill 的唯一入口。
        """
        import shutil
        from core.agent_builder import build_skill_registry, load_config, resolve_workspace, user_root
        cfg = load_config()
        ws = resolve_workspace(None, cfg)
        reg = build_skill_registry(cfg, ws, user_id, docker=False)
        skill = reg.get(name)
        if skill is None or skill.source != "user":
            raise HTTPException(404, f"no user skill to delete: {name!r}")
        # 防穿越:目标必须落在该用户的 .skills 子树内(skill_dir 来自扫描,理应如此,仍兜一层)
        user_skills_dir = (user_root(ws, user_id) / ".skills").resolve()
        target = skill.skill_dir.resolve()
        if user_skills_dir not in target.parents:
            raise HTTPException(400, "拒绝删除 .skills 之外的路径")
        shutil.rmtree(target)

    @app.get("/v1/memory", tags=["memory"])
    def get_memory(user_id: UUID = Depends(require_user)):
        """记忆全貌(只读):core.md 原文 + extended 列表(filename + description)。

        前端「记忆」弹框一次拉满。**只读** —— 改记忆全走对话(agent 自管,见
        `core/memory.py::_CONTRACT`),GUI 当"眼睛"不当"手"(DESIGN §3.7)。
        每次现读 FS(同 skills 端点),agent 刚写的即时可见。
        """
        from core.agent_builder import resolve_workspace
        from core.memory import memory_view
        ws = resolve_workspace(None)
        return memory_view(ws, user_id)

    @app.get("/v1/memory/extended/{filename}", tags=["memory"])
    def get_memory_extended(filename: str, user_id: UUID = Depends(require_user)):
        """读单篇 extended 原文(点开列表项时拉)。文件名非法 / 不存在 → 404。

        路径穿越校验收口在 `core/memory.py::read_extended_file`(只许 `.memory/extended/`
        下扁平 `.md`,再 resolve 兜一层子树)。
        """
        from core.agent_builder import resolve_workspace
        from core.memory import read_extended_file
        ws = resolve_workspace(None)
        content = read_extended_file(ws, user_id, filename)
        if content is None:
            raise HTTPException(404, f"memory file not found: {filename!r}")
        return {"filename": filename, "content": content}
