"""Exporta el workflow actual del grafo de ComfyUI desde la UI via CDP.

Con api_format=True devuelve el API format (el dict que acepta POST /prompt,
extraido de `(await app.graphToPrompt()).output`); con False devuelve el UI graph
serializado (`app.graph.serialize()`, con links y posiciones para volver a
cargar en la UI). Opcionalmente escribe el JSON a disco. Compone cdp_eval.

Funcion impura: hace red (CDP WebSocket) y, si save_path, escribe en disco.
"""
import json
import os

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


def comfyui_export_workflow_ui(
    *,
    port: int = 9222,
    server_url_substr: str = "8188",
    api_format: bool = True,
    save_path: str | None = None,
    timeout_s: float = 15.0,
) -> dict:
    """Exporta el workflow actual del grafo de la UI de ComfyUI.

    Args:
        port: puerto de remote debugging del Chrome diario. Default 9222.
        server_url_substr: substring de la URL de la pestana de ComfyUI.
        api_format: True devuelve el API format (POST /prompt); False devuelve el
            UI graph serializado (recargable con la UI). Default True.
        save_path: si se pasa, ruta donde escribir el JSON exportado. Se expande
            ~ y se crean los directorios padre. None no escribe a disco.
        timeout_s: timeout de la conexion CDP en segundos.

    Returns:
        dict {ok: bool, workflow: dict, saved_to: str|None, error: str}.
    """
    if api_format:
        expr = (
            "(async function(){"
            "  if(!window.app || typeof app.graphToPrompt!=='function'){"
            "    return {error:'window.app.graphToPrompt no disponible en la pestana'};"
            "  }"
            "  try{ var p = await app.graphToPrompt(); return {workflow: p.output, error:''}; }"
            "  catch(e){ return {error:String(e)}; }"
            "})()"
        )
        await_p = True
    else:
        expr = (
            "(function(){"
            "  if(!window.app || !app.graph || typeof app.graph.serialize!=='function'){"
            "    return {error:'window.app.graph.serialize no disponible en la pestana'};"
            "  }"
            "  try{ return {workflow: app.graph.serialize(), error:''}; }"
            "  catch(e){ return {error:String(e)}; }"
            "})()"
        )
        await_p = False

    r = cdp_eval(
        expr,
        port=port,
        target_url_substr=server_url_substr,
        await_promise=await_p,
        timeout_s=timeout_s,
    )
    if not r["ok"]:
        return {"ok": False, "workflow": {}, "saved_to": None, "error": r["error"]}
    val = r["value"] or {}
    if val.get("error"):
        return {"ok": False, "workflow": {}, "saved_to": None, "error": val["error"]}

    workflow = val.get("workflow") or {}
    saved_to = None
    if save_path:
        path = os.path.expanduser(save_path)
        parent = os.path.dirname(path)
        if parent:
            os.makedirs(parent, exist_ok=True)
        with open(path, "w", encoding="utf-8") as fh:
            json.dump(workflow, fh, ensure_ascii=False, indent=2)
        saved_to = path

    return {"ok": True, "workflow": workflow, "saved_to": saved_to, "error": ""}


if __name__ == "__main__":
    out = comfyui_export_workflow_ui(api_format=True)
    print(json.dumps(
        {"ok": out["ok"], "nodes": len(out["workflow"]), "error": out["error"]},
        ensure_ascii=False, indent=2,
    ))
