"""
Genera los flujos n8n del Monitor de Facturas a partir del flujo original exportado.

  python3 generar_flujos.py

Salida:
  - "Facturas - Captura y fusion semanal (monitor).json"  -> flujo original + registro de CIF rechazado
  - "Fragmento para pegar en flujo principal.json"        -> el nodo nuevo, para pegar con Ctrl+V
"""
import copy
import json
import uuid
from pathlib import Path

AQUI = Path(__file__).parent
ORIGINAL = AQUI / "original - Facturas - Captura y fusion semanal (8).json"



def uid():
    return str(uuid.uuid4())


wf = json.loads(ORIGINAL.read_text())
WORKFLOW_ID = wf["id"]
nodos = {n["name"]: n for n in wf["nodes"]}
marcar = nodos["Marcar fusionadas"]
cred_sheets = marcar["credentials"]
schema_base = marcar["parameters"]["columns"]["schema"]


def schema(visibles):
    s = copy.deepcopy(schema_base)
    for c in s:
        c["removed"] = c["id"] not in visibles
    return s


def sheets_update(nombre, valores, pos):
    """appendOrUpdate sobre la hoja de registros, casando por 'Archivo temporal'."""
    p = copy.deepcopy(marcar["parameters"])
    p["columns"]["value"] = valores
    p["columns"]["schema"] = schema(set(valores))
    return {
        "parameters": p,
        "type": "n8n-nodes-base.googleSheets",
        "typeVersion": 4.7,
        "position": pos,
        "id": uid(),
        "name": nombre,
        "credentials": cred_sheets,
    }


def webhook(nombre, metodo, path, pos):
    return {
        "parameters": {
            "httpMethod": metodo,
            "path": path,
            "authentication": "headerAuth",
            "responseMode": "responseNode",
            "options": {"allowedOrigins": "*"},
        },
        "type": "n8n-nodes-base.webhook",
        "typeVersion": 2,
        "position": pos,
        "id": uid(),
        "webhookId": uid(),
        "name": nombre,
        "credentials": CRED_TOKEN,
    }


def respuesta(nombre, pos, cuerpo="={{ JSON.stringify($json) }}", codigo=None):
    opts = {
        "responseHeaders": {
            "entries": [
                {"name": "Access-Control-Allow-Origin", "value": "*"},
                {"name": "Cache-Control", "value": "no-store"},
            ]
        }
    }
    if codigo:
        opts["responseCode"] = codigo
    return {
        "parameters": {"respondWith": "json", "responseBody": cuerpo, "options": opts},
        "type": "n8n-nodes-base.respondToWebhook",
        "typeVersion": 1.1,
        "position": pos,
        "id": uid(),
        "name": nombre,
    }


def code(nombre, js, pos):
    return {
        "parameters": {"jsCode": js},
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": pos,
        "id": uid(),
        "name": nombre,
    }


def conectar(conns, origen, destinos, salida=0):
    main = conns.setdefault(origen, {"main": []})["main"]
    while len(main) <= salida:
        main.append([])
    main[salida] = [{"node": d, "type": "main", "index": 0} for d in destinos]


# ---------------------------------------------------------------------------
# 1) Flujo original parcheado
# ---------------------------------------------------------------------------
principal = copy.deepcopy(wf)
principal["name"] = wf["name"]
conns = principal["connections"]

# 1a. Registrar en el Excel las facturas rechazadas por CIF (hoy no quedan marcadas).
aviso_cif = nodos["Aviso CIF faltante o incorrecto"]
x, y = aviso_cif["position"]
reg_cif = sheets_update(
    "Registrar CIF rechazado Excel",
    {
        "Archivo temporal": "={{ $('Añadir metadatos').item.json.nombre_archivo }}",
        "Fusionada": "=RECHAZADA · CIF/VAT no válido ({{ $now.toFormat('yyyy-MM-dd HH:mm') }})",
    },
    [x + 112, y - 208],
)
reg_cif["onError"] = "continueRegularOutput"
principal["nodes"].append(reg_cif)
conectar(conns, "Aviso CIF faltante o incorrecto", ["Registrar CIF rechazado Excel"])
conectar(conns, "Registrar CIF rechazado Excel", ["Resultado: CIF"])

bx, by = nodos["Abrir Formulario"]["position"]

principal["nodes"].append({
    "parameters": {
        "content": "## Monitor de facturas\nAñadido para facturas-monitor.php:\n- **Registrar CIF rechazado Excel**: deja la fila marcada como RECHAZADA en *Fusionada*.\n\nEl panel marca estados escribiendo en *Fusionada* / *Duplicado de*; 'Filtrar pendientes' ya ignora toda fila con *Fusionada* rellena.",
        "height": 260,
        "width": 760,
        "color": 5,
    },
    "type": "n8n-nodes-base.stickyNote",
    "typeVersion": 1,
    "position": [x + 40, y - 520],
    "id": uid(),
    "name": "Sticky Note Monitor",
})

# Sin id/versionId para que n8n lo importe como copia y no pise el flujo en producción.
for k in ("id", "versionId", "active", "pinData"):
    principal.pop(k, None)
principal["name"] = wf["name"] + " (monitor)"
(AQUI / "Facturas - Captura y fusion semanal (monitor).json").write_text(
    json.dumps(principal, ensure_ascii=False, indent=2)
)

# ---------------------------------------------------------------------------
# 3) Fragmento para pegar (Ctrl+V) en el flujo de producción sin cambiar su ID
# ---------------------------------------------------------------------------
nuevos = [reg_cif]
fragmento = {
    "nodes": nuevos,
    "connections": {k: v for k, v in conns.items() if k in {n["name"] for n in nuevos}},
}
(AQUI / "Fragmento para pegar en flujo principal.json").write_text(
    json.dumps(fragmento, ensure_ascii=False, indent=2)
)
print("OK ·", WORKFLOW_ID, "·", len(principal["nodes"]), "nodos")
