#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Fase 2 — MARCA → SUCURSAL V2: match directo por id_contacto_sucursal.

Insertar entre `Datos API Cuenta objetivo - SUCURSAL` y
`Buscar Contacto Objetivo - SUCURSAL(mail)`:
  1) Code `Extraer id_contacto_sucursal de Marca` — saca CF del contacto Marca.
  2) IF `¿cfValue presente?` — si vacío salta directo a cascada email.
  3) HTTP GET `Match directo por id_contacto_sucursal` — GET /contacts/{cfValue}
     con token sucursal. onError: continueRegularOutput.
  4) IF `¿GET de contacto sucursal OK?` — true→Conseguir Custom...SUCURSAL (UPDATE),
     false→cascada email.

Uso:
    python n8n/_apply_phase2.py            # dry-run
    python n8n/_apply_phase2.py --apply [--activate]
"""
import argparse
import copy
import json
import os
import sys
import uuid

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, ROOT)
sys.path.insert(0, os.path.join(ROOT, "scripts"))
from n8n_workflow_lib import load_credentials, N8NClient  # noqa: E402

WID = "4UMRwxJdHFfOGHBp"
CF_ID_BRAND = "E6lI9ykWhqpj7Pmi7Qd3"

CODE_EXTRACT_NAME = "Extraer id_contacto_sucursal de Marca"
IF_CF_PRESENT_NAME = "¿cfValue presente?"
HTTP_GET_NAME = "Match directo por id_contacto_sucursal"
IF_GET_OK_NAME = "¿GET de contacto sucursal OK?"


def code_extract_node():
    return {
        "parameters": {
            "jsCode": (
                "var c = $('Obtener Contacto Cuenta Origen - SUCURSAL').first().json.contact || {};\n"
                "var cfs = c.customFields || [];\n"
                "var v = null;\n"
                "for (var i = 0; i < cfs.length; i++) {\n"
                "  if (cfs[i].id === '" + CF_ID_BRAND + "') { v = cfs[i].value; break; }\n"
                "}\n"
                "return [{ json: { cfValue: v || null } }];"
            )
        },
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [1376, 416],
        "id": str(uuid.uuid4()),
        "name": CODE_EXTRACT_NAME,
        "notes": "FASE 2. Extrae el valor del CF id_contacto_sucursal del contacto Marca origen.",
    }


def if_cf_present_node():
    return {
        "parameters": {
            "conditions": {
                "options": {
                    "caseSensitive": True,
                    "leftValue": "",
                    "typeValidation": "loose",
                    "version": 3,
                },
                "conditions": [
                    {
                        "id": str(uuid.uuid4()),
                        "leftValue": "={{ $json.cfValue }}",
                        "rightValue": "",
                        "operator": {"type": "string", "operation": "notEmpty", "singleValue": True},
                    }
                ],
                "combinator": "and",
            },
            "options": {},
        },
        "type": "n8n-nodes-base.if",
        "typeVersion": 2,
        "position": [1568, 416],
        "id": str(uuid.uuid4()),
        "name": IF_CF_PRESENT_NAME,
        "notes": "true→HTTP GET, false→cascada email",
    }


def http_get_node():
    return {
        "parameters": {
            "method": "GET",
            "url": "=https://services.leadconnectorhq.com/contacts/{{ $('" + CODE_EXTRACT_NAME + "').item.json.cfValue }}",
            "sendHeaders": True,
            "headerParameters": {
                "parameters": [
                    {"name": "Version", "value": "2021-07-28"},
                    {"name": "Authorization",
                     "value": "=Bearer {{ $('Datos API Cuenta objetivo - SUCURSAL').item.json['Token/API'] }}"},
                ]
            },
            "options": {"redirect": {"redirect": {}}},
        },
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.2,
        "position": [1760, 416],
        "id": str(uuid.uuid4()),
        "name": HTTP_GET_NAME,
        "onError": "continueRegularOutput",
        "alwaysOutputData": True,
        "notes": "GET directo a sucursal por id (el valor del CF). Si 404, IF siguiente cae a cascada.",
    }


def if_get_ok_node():
    return {
        "parameters": {
            "conditions": {
                "options": {
                    "caseSensitive": True,
                    "leftValue": "",
                    "typeValidation": "loose",
                    "version": 3,
                },
                "conditions": [
                    {
                        "id": str(uuid.uuid4()),
                        "leftValue": "={{ $json.contact && $json.contact.id ? 'ok' : '' }}",
                        "rightValue": "",
                        "operator": {"type": "string", "operation": "notEmpty", "singleValue": True},
                    }
                ],
                "combinator": "and",
            },
            "options": {},
        },
        "type": "n8n-nodes-base.if",
        "typeVersion": 2,
        "position": [1952, 416],
        "id": str(uuid.uuid4()),
        "name": IF_GET_OK_NAME,
        "notes": "true→UPDATE (Conseguir Custom Cuenta objetivo - SUCURSAL), false→cascada email",
    }


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--apply", action="store_true")
    parser.add_argument("--activate", action="store_true")
    args = parser.parse_args()
    if hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8")

    client = N8NClient(*load_credentials())
    wf, backup = client.backup_workflow(WID, label="fase2_pre")
    print(f"backup: {backup}")
    prev = wf.get("versionId")
    print(f"versionId pre: {prev}  active: {wf.get('active')}  nodes: {len(wf['nodes'])}")

    wfm = copy.deepcopy(wf)
    for name in (CODE_EXTRACT_NAME, IF_CF_PRESENT_NAME, HTTP_GET_NAME, IF_GET_OK_NAME):
        try:
            client.assert_idempotent(wfm, name)
        except Exception as e:
            raise SystemExit(f"Aborto: {e}")

    # Insertar nodos
    code_node = code_extract_node()
    if_cf = if_cf_present_node()
    http_get = http_get_node()
    if_ok = if_get_ok_node()
    for n in (code_node, if_cf, http_get, if_ok):
        client.add_node(wfm, n)

    # Conexiones:
    #   Datos API Cuenta objetivo - SUCURSAL → Code Extract
    #   Code Extract → IF cfValue presente
    #     true → HTTP GET
    #            → IF GET OK
    #               true → Conseguir Custom Cuenta objetivo - SUCURSAL
    #               false → Buscar Contacto Objetivo - SUCURSAL(mail)
    #     false → Buscar Contacto Objetivo - SUCURSAL(mail)
    client.set_connection(wfm, "Datos API Cuenta objetivo - SUCURSAL", CODE_EXTRACT_NAME)
    client.set_connection(wfm, CODE_EXTRACT_NAME, IF_CF_PRESENT_NAME)
    client.branch_if(wfm, IF_CF_PRESENT_NAME,
                     true_target=HTTP_GET_NAME,
                     false_target="Buscar Contacto Objetivo - SUCURSAL(mail)")
    client.set_connection(wfm, HTTP_GET_NAME, IF_GET_OK_NAME)
    client.branch_if(wfm, IF_GET_OK_NAME,
                     true_target="Conseguir Custom Cuenta objetivo - SUCURSAL",
                     false_target="Buscar Contacto Objetivo - SUCURSAL(mail)")

    print(f"nodes post: {len(wfm['nodes'])}  (+{len(wfm['nodes'])-len(wf['nodes'])})")

    if not args.apply:
        res = client.put_workflow(WID, wfm, dry_run=True)
        print(f"DRY-RUN. {res['path']}")
        return

    client.put_workflow(WID, wfm, dry_run=False)
    wf2 = client.verify_post(WID,
                             expected_node_names=[CODE_EXTRACT_NAME, IF_CF_PRESENT_NAME,
                                                  HTTP_GET_NAME, IF_GET_OK_NAME],
                             prev_version_id=prev)
    print(f"versionId nuevo: {wf2.get('versionId')}  active: {wf2.get('active')}")
    if args.activate or not wf2.get("active"):
        client.activate(WID)
        print("activado")

    print("Fase 2 aplicada.")


if __name__ == "__main__":
    main()
