#!/usr/bin/env python3
"""
Corrige contatos já enviados ao CRM Sweet Angels (GHL) preenchendo os
campos customizados que ficaram vazios no envio original.

Uso:
    python3 fix_campos_sweet_angels.py
"""

import json
import re
import sys
import time
from pathlib import Path

import requests

# ── Config ────────────────────────────────────────────
TOKEN = "pit-0198bd77-3df3-4da6-93e7-bc50db3a5d86"
LOCATION_ID = "4z6Fjpgj2soAQZpu8Ddk"
LEADS_PATH = Path("/opt/mia/workspace/prospeccao_ativa/enriq_leads/f29a0543.json")
GHL_BASE = "https://services.leadconnectorhq.com"

CAMPOS_MAP = {
    "cnpj":                  "OXuuJ2qaOS3Rft8yYYbM",
    "decisor_nome":          "yQn9XjbldhCuAQ2QBhEl",
    "decisor_cargo":         "42XmykBk5o1JzL2YgcHn",
    "linkedin_url":          "AhzLozPJlwPMrNRGmOvs",
    "instagram":             "hGNaQL49126z2H8R1nfl",
    "facebook":              "0wnPrPvRnH0TM4RDf5H9",
    "site":                  "HTynXy6CmQBknlpaGxBH",
    "fontes_enriquecimento": "5h6WOTvC5ZNrZhcuzQVL",
}

# Campos que definem se vale a pena tentar atualizar
CAMPOS_MIN = ("cnpj", "instagram", "decisor_nome", "linkedin_url", "facebook")

HEADERS = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Version": "2021-07-28",
}


# ── Helpers ───────────────────────────────────────────
def so_digitos(s: str) -> str:
    return re.sub(r"\D", "", s or "")


def primeiro_telefone(raw: str) -> str:
    """Retorna o 1o telefone (só dígitos) de uma string tipo '(11) 4612-3600 / (11) 2914-1406'."""
    if not raw:
        return ""
    partes = re.split(r"[/,;|]", raw)
    for p in partes:
        d = so_digitos(p)
        if len(d) >= 8:
            return d
    return so_digitos(raw)


def buscar_contato(query: str) -> list:
    try:
        r = requests.get(
            f"{GHL_BASE}/contacts/",
            params={"locationId": LOCATION_ID, "query": query},
            headers=HEADERS,
            timeout=20,
        )
        if r.status_code == 200:
            return r.json().get("contacts", []) or []
        print(f"    [busca HTTP {r.status_code}] {r.text[:120]}")
    except Exception as e:
        print(f"    [erro busca] {e}")
    return []


def match_por_telefone(contatos: list, tel_digitos: str) -> dict | None:
    if not tel_digitos:
        return None
    tail = tel_digitos[-8:]  # últimos 8 dígitos são o mais discriminante
    for c in contatos:
        for campo in ("phone", "phoneNumber"):
            v = so_digitos(c.get(campo) or "")
            if v and v.endswith(tail):
                return c
    return None


def match_por_nome(contatos: list, nome: str) -> dict | None:
    alvo = (nome or "").strip().lower()
    if not alvo:
        return None
    for c in contatos:
        cn = (c.get("companyName") or "").strip().lower()
        if cn and (cn == alvo or alvo in cn or cn in alvo):
            return c
    for c in contatos:
        full = f"{c.get('firstName') or ''} {c.get('lastName') or ''}".strip().lower()
        if full and (full == alvo or alvo in full or full in alvo):
            return c
    return None


def montar_custom_fields(lead: dict) -> list:
    cf = []
    for campo, field_id in CAMPOS_MAP.items():
        if campo == "fontes_enriquecimento":
            fontes = lead.get("fontes") or []
            if fontes:
                cf.append({"id": field_id, "value": ", ".join(fontes)})
            continue
        v = lead.get(campo)
        if v:
            cf.append({"id": field_id, "value": str(v)})
    return cf


def atualizar_contato(contact_id: str, custom_fields: list) -> tuple[bool, str]:
    try:
        r = requests.put(
            f"{GHL_BASE}/contacts/{contact_id}",
            headers=HEADERS,
            json={"customFields": custom_fields},
            timeout=20,
        )
        if r.status_code in (200, 201):
            return True, ""
        try:
            msg = r.json().get("message") or r.json().get("msg") or str(r.json())[:200]
        except Exception:
            msg = r.text[:200]
        return False, f"HTTP {r.status_code}: {msg}"
    except Exception as e:
        return False, f"exceção: {e}"


# ── Main ──────────────────────────────────────────────
def main():
    if not LEADS_PATH.exists():
        print(f"ERRO: arquivo não encontrado: {LEADS_PATH}")
        sys.exit(1)

    leads = json.loads(LEADS_PATH.read_text(encoding="utf-8"))
    print(f"Carregados {len(leads)} leads de {LEADS_PATH.name}")
    print(f"Location: {LOCATION_ID}\n")

    atualizados = 0
    nao_encontrados = 0
    com_erro = 0
    pulados = 0

    for i, lead in enumerate(leads, 1):
        nome = (lead.get("nome") or "").strip()
        if not nome:
            pulados += 1
            continue

        tem_algo = any(lead.get(c) for c in CAMPOS_MIN)
        if not tem_algo:
            pulados += 1
            print(f"[{i:03d}] {nome} → sem campos customizados, pulando")
            continue

        cf = montar_custom_fields(lead)
        if not cf:
            pulados += 1
            print(f"[{i:03d}] {nome} → nenhum valor a atualizar, pulando")
            continue

        tel = primeiro_telefone(lead.get("telefone") or "")
        contato = None

        if tel:
            contatos = buscar_contato(tel)
            contato = match_por_telefone(contatos, tel) or match_por_nome(contatos, nome)

        if not contato:
            contatos = buscar_contato(nome)
            contato = match_por_nome(contatos, nome) or match_por_telefone(contatos, tel)

        if not contato:
            nao_encontrados += 1
            print(f"[{i:03d}] {nome} → NAO ENCONTRADO (tel={tel or '-'})")
            time.sleep(0.5)
            continue

        contact_id = contato.get("id")
        ok, err = atualizar_contato(contact_id, cf)
        campos_nomes = [c["id"] for c in cf]
        # Traduzir de field_id → nome do campo pra log ficar legível
        inv = {v: k for k, v in CAMPOS_MAP.items()}
        campos_legiveis = [inv.get(fid, fid) for fid in campos_nomes]

        if ok:
            atualizados += 1
            print(f"[{i:03d}] {nome} → OK ({contact_id}) campos={campos_legiveis}")
        else:
            com_erro += 1
            print(f"[{i:03d}] {nome} → ERRO ({contact_id}) {err}")

        time.sleep(0.5)

    print("\n" + "=" * 60)
    print("RESUMO:")
    print(f"  Atualizados     : {atualizados}")
    print(f"  Não encontrados : {nao_encontrados}")
    print(f"  Com erro        : {com_erro}")
    print(f"  Pulados         : {pulados}")
    print(f"  Total lidos     : {len(leads)}")
    print("=" * 60)


if __name__ == "__main__":
    main()
