"""Construye el workflow minimo de un visor 3D nativo de ComfyUI (Load3D).

ComfyUI 0.26.0 trae el nodo nativo `Load3D` (display "Load 3D & Animation",
`comfy_extras.nodes_load_3d`, categoria `3d`): un visor Three.js embebido que
renderiza un GLB/GLTF/OBJ/FBX/STL/PLY **en el frontend, sin ejecutar el grafo**
(no es output node). Sirve para VER un mesh ya existente con su textura/color,
orbitando con el raton, dentro de un nodo de la UI.

Este builder devuelve el dict API-format (un unico nodo) cargable en la UI con
`comfyui_load_workflow_ui`. La variante se elige con `animation`:

  - animation=False -> `Load3D` (visor estandar; input `image` de estado del
    visor; el usado en el report 0079). Reproduce animaciones embebidas del
    modelo en el frontend.
  - animation=True  -> `Load3DAdvanced` (display "Load 3D (Advanced)"; input
    `viewport_state` en vez de `image`): mismo visor con control avanzado de
    camara/viewport, mejor para inspeccionar la orbita de un modelo animado.

Funcion pura: sin red, sin I/O. Determinista para los mismos argumentos.

GOTCHA: `Load3D`/`Load3DAdvanced` solo listan/cargan archivos que esten bajo
`~/ComfyUI/input/3d/`. `model_file` debe ser la ruta RELATIVA a `input/`
(p.ej. "3d/fox.glb"). Copiar el GLB ahi es I/O, fuera de esta funcion pura.
"""


def comfyui_build_view_3d_workflow(
    model_file: str,
    *,
    animation: bool = False,
    width: int = 1024,
    height: int = 1024,
) -> dict:
    """Monta el API-format de un visor 3D minimo para un GLB/GLTF/OBJ existente.

    Args:
        model_file: ruta del modelo RELATIVA al `input/` del servidor ComfyUI
            (p.ej. "3d/fox_mv_textured.glb"). El archivo debe existir ya bajo
            `~/ComfyUI/input/3d/` para que el visor lo cargue.
        animation: si True usa `Load3DAdvanced` (control avanzado de
            camara/viewport, apto para inspeccionar modelos animados); si False
            (default) usa `Load3D`, el visor estandar del report 0079. Ambos
            reproducen animaciones embebidas del modelo en el frontend.
            keyword-only.
        width: ancho del viewport del nodo en px. keyword-only.
        height: alto del viewport del nodo en px. keyword-only.

    Returns:
        dict en API format con un unico nodo "1". Con animation=False:
        {"1": {"class_type": "Load3D", "inputs": {"model_file", "image",
        "width", "height"}}}; con animation=True el class_type es
        "Load3DAdvanced" y el segundo input es "viewport_state". Cargable con
        comfyui_load_workflow_ui (inyecta en la UI) o POSTeable a /prompt.
    """
    if animation:
        return {
            "1": {
                "class_type": "Load3DAdvanced",
                "inputs": {
                    "model_file": model_file,
                    "viewport_state": "",
                    "width": width,
                    "height": height,
                },
            }
        }
    return {
        "1": {
            "class_type": "Load3D",
            "inputs": {
                "model_file": model_file,
                "image": "",
                "width": width,
                "height": height,
            },
        }
    }


if __name__ == "__main__":
    import json

    wf = comfyui_build_view_3d_workflow("3d/fox_mv_textured.glb")
    print(json.dumps(wf, indent=2))
    wf_anim = comfyui_build_view_3d_workflow("3d/walk_cycle.glb", animation=True)
    print(json.dumps(wf_anim, indent=2))
