"""comfyui_list_skills — lista las *skills* ComfyUI guardadas en la libreria de disco.

Escanea `<library_dir>/<slug>/recipe.json` y devuelve un resumen por skill: slug, title,
base_workflow, version, score_mean/score_n (del bucle de scoring) y nsfw (de
`provenance.nsfw`), mas el numero de snapshots en `versions/`.

Respeta `include_nsfw=False` (por defecto): oculta las skills marcadas NSFW. Una libreria
inexistente o vacia devuelve una lista vacia sin error.

Impura: lee el arbol de la libreria en disco.
"""

import json
import os

DEFAULT_LIBRARY = "~/ComfyUI/skills_library"


def _lib_dir(library_dir):
    return os.path.expanduser(library_dir or DEFAULT_LIBRARY)


def _n_versions(skill_dir):
    versions_dir = os.path.join(skill_dir, "versions")
    if not os.path.isdir(versions_dir):
        return 0
    return len([f for f in os.listdir(versions_dir)
                if f.startswith("v") and f.endswith(".json")])


def comfyui_list_skills(library_dir: str = None, include_nsfw: bool = False) -> dict:
    """Lista las skills de la libreria con su metadata de resumen.

    Args:
        library_dir: raiz de la libreria. Default `~/ComfyUI/skills_library`.
        include_nsfw: si False (default), oculta las skills con `provenance.nsfw == True`.

    Returns:
        dict ``{ok, skills, count, error}`` donde `skills` es una lista de dicts
        ``{slug, title, base_workflow, version, score_mean, score_n, nsfw, n_versions}``
        ordenada por slug. Libreria inexistente -> lista vacia, ``ok=True``. Nunca lanza.
    """
    lib = _lib_dir(library_dir)
    if not os.path.isdir(lib):
        return {"ok": True, "skills": [], "count": 0, "error": ""}

    skills = []
    try:
        entries = sorted(os.listdir(lib))
    except OSError as exc:
        return {"ok": False, "skills": [], "count": 0, "error": f"no se pudo listar la libreria: {exc}"}

    for slug in entries:
        skill_dir = os.path.join(lib, slug)
        recipe_path = os.path.join(skill_dir, "recipe.json")
        if not os.path.isfile(recipe_path):
            continue
        try:
            with open(recipe_path, encoding="utf-8") as fh:
                r = json.load(fh)
        except (OSError, json.JSONDecodeError):
            continue

        prov = r.get("provenance") or {}
        nsfw = bool(prov.get("nsfw"))
        if nsfw and not include_nsfw:
            continue

        skills.append({
            "slug": r.get("slug", slug),
            "title": r.get("title", ""),
            "base_workflow": r.get("base_workflow", ""),
            "version": r.get("version", ""),
            "score_mean": r.get("score_mean", 0),
            "score_n": r.get("score_n", 0),
            "nsfw": nsfw,
            "n_versions": _n_versions(skill_dir),
        })

    return {"ok": True, "skills": skills, "count": len(skills), "error": ""}


if __name__ == "__main__":
    res = comfyui_list_skills(library_dir="/tmp/skills_demo")
    print(json.dumps(res, indent=2, ensure_ascii=False))
