# -*- coding: utf-8 -*-
"""Fallback de autoenlace para el workflow Sucursal->Marca (x4DqZ5FtSc43tdzB).

Inserta entre 'Mapear Custom Fields Cuenta Origen - SUCURSAL' y
'DATOS CUENTA OBJETIVO' un IF + PUT condicional:
  - Si el CF 'contact.id_contacto_sucursal' ya == contact.id  -> bypass directo.
  - Si NO -> PUT autoenlace en la sucursal antes de continuar.

Defensivo contra automatizaciones nativas de GHL que crean contactos sin
disparar nuestro fill. onError=continueRegularOutput para no romper el sync
si el PUT falla.

Modo dry-run por defecto (dumpea n8n/dryrun_*.json sin tocar la API).
Pasar --apply para PUT real + reactivar.
"""
import argparse
import sys
import os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from scripts.n8n_workflow_lib import load_credentials, N8NClient
import uuid

WID = "x4DqZ5FtSc43tdzB"

NAME_IF = "ya esta el CF id_contacto_sucursal"
NAME_PUT = "Autoenlace CF id_contacto_sucursal - SUCURSAL"

SRC = "Mapear Custom Fields Cuenta Origen - SUCURSAL"
DST = "DATOS CUENTA OBJETIVO"


def build_if_node():
    return {
        "parameters": {
            "conditions": {
                "options": {
                    "caseSensitive": True,
                    "leftValue": "",
                    "typeValidation": "strict",
                    "version": 2,
                },
                "conditions": [
                    {
                        "id": str(uuid.uuid4()),
                        "leftValue": "={{ $json['contact.id_contacto_sucursal'] }}",
                        "rightValue": "={{ $json.id }}",
                        "operator": {
                            "type": "string",
                            "operation": "equals",
                            "name": "filter.operator.equals",
                        },
                    }
                ],
                "combinator": "and",
            },
            "options": {},
        },
        "type": "n8n-nodes-base.if",
        "typeVersion": 2.2,
        "position": [1760, -288],
        "id": str(uuid.uuid4()),
        "name": NAME_IF,
        "notes": (
            "Fallback defensivo. Si el CF 'contact.id_contacto_sucursal' ya == contact.id "
            "(estado normal poblado por fill_contact_id_sucursal.py), pasa directo. "
            "Si esta vacio o distinto (creacion por automatizacion nativa de GHL que se "
            "salto nuestro fill), va a la rama PUT para autoenlazar antes de tocar Marca."
        ),
    }


def build_put_node():
    json_body = (
        "={{ JSON.stringify({ customFields: [ { "
        "id: $('Conseguir Custom Cuenta Origen- SUCURSAL').first().json.customFields"
        ".find(f => f.fieldKey === 'contact.id_contacto_sucursal')?.id, "
        "key: 'contact.id_contacto_sucursal', "
        "field_value: $('Mapear Custom Fields Cuenta Origen - SUCURSAL').item.json.id"
        " } ] }) }}"
    )
    return {
        "parameters": {
            "method": "PUT",
            "url": (
                "=https://services.leadconnectorhq.com/contacts/"
                "{{ $('Mapear Custom Fields Cuenta Origen - SUCURSAL').item.json.id }}"
            ),
            "sendHeaders": True,
            "headerParameters": {
                "parameters": [
                    {"name": "Accept", "value": "application/json"},
                    {"name": "Version", "value": "2021-07-28"},
                    {
                        "name": "Authorization",
                        "value": (
                            "=Bearer "
                            "{{ $('Obtener Info de cuenta origen - SUCURSAL').item.json.API_token }}"
                        ),
                    },
                    {"name": "Content-Type", "value": "application/json"},
                ]
            },
            "sendBody": True,
            "specifyBody": "json",
            "jsonBody": json_body,
            "options": {},
        },
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.2,
        "position": [1936, -192],
        "id": str(uuid.uuid4()),
        "name": NAME_PUT,
        "onError": "continueRegularOutput",
        "notes": (
            "Autoenlace de seguridad: setea CF 'contact.id_contacto_sucursal' = "
            "contact.id propio en la sucursal. Solo se ejecuta si el IF previo "
            "detecto que el CF estaba vacio o distinto. onError=continue para no "
            "romper el sync si el PUT falla."
        ),
    }


def parse_args():
    ap = argparse.ArgumentParser()
    ap.add_argument("--apply", action="store_true",
                    help="Aplicar PUT real (default: dry-run a n8n/dryrun_*.json)")
    return ap.parse_args()


def main():
    args = parse_args()
    api_key, base_url = load_credentials()
    client = N8NClient(api_key, base_url)

    print(f"[1/6] GET workflow {WID}")
    wf = client.get_workflow(WID)
    print(f"      versionId previo: {wf.get('versionId')}")
    print(f"      active          : {wf.get('active')}")
    print(f"      total nodos     : {len(wf.get('nodes') or [])}")

    existing = {n["name"] for n in wf.get("nodes") or []}
    if NAME_IF in existing or NAME_PUT in existing:
        print(f"\nERROR: los nodos ya existen ({NAME_IF!r} o {NAME_PUT!r}). Abortando.")
        sys.exit(2)
    if SRC not in existing:
        print(f"\nERROR: no encontre el nodo source {SRC!r}. Abortando.")
        sys.exit(2)
    if DST not in existing:
        print(f"\nERROR: no encontre el nodo destino {DST!r}. Abortando.")
        sys.exit(2)

    print(f"\n[2/6] Backup fresco")
    _, bpath = client.backup_workflow(WID, label="pre_fallback_autoenlace")
    print(f"      backup -> {bpath}")

    print(f"\n[3/6] Inyectar nodos IF + PUT")
    if_node = build_if_node()
    put_node = build_put_node()
    client.add_node(wf, if_node)
    client.add_node(wf, put_node)
    print(f"      IF : {NAME_IF}")
    print(f"      PUT: {NAME_PUT}")

    print(f"\n[4/6] Reconectar grafo")
    # Reemplaza SRC -> DST por SRC -> IF
    client.insert_between(wf, SRC, NAME_IF, DST)
    # IF.output(0)=true (CF ya ok) -> DST; IF.output(1)=false (CF vacio/distinto) -> PUT -> DST
    client.branch_if(wf, NAME_IF, true_target=DST, false_target=NAME_PUT)
    # PUT -> DST (convergencia)
    conns = wf["connections"]
    conns[NAME_PUT] = {"main": [[{"node": DST, "type": "main", "index": 0}]]}
    print(f"      {SRC} -> {NAME_IF}")
    print(f"      {NAME_IF} [true]  -> {DST}")
    print(f"      {NAME_IF} [false] -> {NAME_PUT}")
    print(f"      {NAME_PUT} -> {DST}")

    print(f"\n[5/6] {'APPLY' if args.apply else 'DRY-RUN'} put_workflow")
    result = client.put_workflow(WID, wf, dry_run=not args.apply)
    if not args.apply:
        print(f"      dry-run dump -> {result}")
        print("\nLISTO. Revisa el JSON. Si todo bien, corre con --apply.")
        return

    print(f"\n[6/6] Verificar y reactivar")
    new_wf = client.verify_post(
        WID,
        expected_node_names=[NAME_IF, NAME_PUT],
        prev_version_id=wf.get("versionId"),
    )
    print(f"      versionId nuevo: {new_wf.get('versionId')}")
    if not new_wf.get("active"):
        print("      workflow quedo inactivo tras PUT; reactivando...")
        client.activate(WID)
        new_wf = client.get_workflow(WID)
    print(f"      active final   : {new_wf.get('active')}")
    print(f"      total nodos    : {len(new_wf.get('nodes') or [])}")
    print("\nOK.")


if __name__ == "__main__":
    main()
