"""Carga un workflow ComfyUI (API format) en la UI del navegador via CDP.

Inyecta `app.loadApiJson(<workflow>, filename)` en la pestana de ComfyUI ya
abierta en el navegador diario, reconstruyendo el grafo visual a partir del API
format (el mismo dict que produce comfyui_build_txt2img_workflow). Compone la
primitiva de transport cdp_eval; no abre ventana nueva ni reinventa CDP.

Funcion impura: hace red (CDP WebSocket) y muta el grafo de la UI.
"""
import json

try:  # ejecucion directa del archivo / fn run (browser/ en sys.path[0])
    from cdp_eval import cdp_eval
    from comfyui_clear_node_outputs_ui import comfyui_clear_node_outputs_ui
except ImportError:  # importado como paquete (sys.path = python/functions)
    from browser.cdp_eval import cdp_eval
    from browser.comfyui_clear_node_outputs_ui import comfyui_clear_node_outputs_ui


def comfyui_load_workflow_ui(
    workflow: dict,
    *,
    port: int = 9222,
    server_url_substr: str = "8188",
    filename: str = "workflow.json",
    clear_outputs: bool = True,
    timeout_s: float = 20.0,
) -> dict:
    """Carga un workflow API format en el grafo de la UI de ComfyUI.

    Args:
        workflow: dict en API format (claves = node_ids, valores con class_type +
            inputs). Tipicamente el resultado de comfyui_build_txt2img_workflow.
        port: puerto de remote debugging del Chrome diario. Default 9222.
        server_url_substr: substring de la URL de la pestana de ComfyUI (default
            "8188", el puerto del server). Identifica la pestana entre todas las
            abiertas.
        filename: nombre que ComfyUI asocia al workflow cargado.
        clear_outputs: si True (default), limpia los previews/outputs residuales
            (app.nodeOutputs + node.imgs) ANTES de cargar, replicando lo que hace
            la ruta del menu (app.clean()). Evita que un preview cacheado de un
            workflow anterior se pegue a un nodo nuevo que reusa el mismo node_id
            (bug de imagenes residuales). Ponlo en False solo si quieres conservar
            a proposito los previews del grafo previo.
        timeout_s: timeout de la conexion CDP en segundos.

    Returns:
        dict {ok: bool, loaded: bool, error: str}. ok/loaded True si
        app.loadApiJson termino sin excepcion en la pagina.
    """
    if clear_outputs:
        comfyui_clear_node_outputs_ui(
            port=port,
            server_url_substr=server_url_substr,
            timeout_s=timeout_s,
        )
    expr = (
        "(async function(){"
        "  if(!window.app || typeof app.loadApiJson!=='function'){"
        "    return {loaded:false, error:'window.app.loadApiJson no disponible en la pestana'};"
        "  }"
        "  try{"
        f"    await app.loadApiJson({json.dumps(workflow)}, {json.dumps(filename)});"
        "    return {loaded:true, error:'', nodes: app.graph? app.graph._nodes.length : -1};"
        "  }catch(e){ return {loaded:false, error:String(e)}; }"
        "})()"
    )
    r = cdp_eval(
        expr,
        port=port,
        target_url_substr=server_url_substr,
        await_promise=True,
        timeout_s=timeout_s,
    )
    if not r["ok"]:
        return {"ok": False, "loaded": False, "error": r["error"]}
    val = r["value"] or {}
    return {
        "ok": bool(val.get("loaded")),
        "loaded": bool(val.get("loaded")),
        "error": val.get("error", ""),
    }


if __name__ == "__main__":
    import os
    import sys

    sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
    from ml.comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow

    wf = comfyui_build_txt2img_workflow(
        ckpt_name="IMG_v1-5-pruned-emaonly-fp16.safetensors",
        positive="a red apple on a wooden table, sharp focus",
    )
    print(json.dumps(comfyui_load_workflow_ui(wf), ensure_ascii=False, indent=2))
