"""
GoHighLevel (Linkia) API client — Sweet Angels SDR Medio Porte.

Clone do ghl_client.py do sdr_fesqua. Unica diferenca:
DEFAULT_PIPELINE_ID vem de env (LINKIA_PIPELINE_ID_MEDIO_PORTE) porque
o pipeline dessa campanha ainda vai ser criado pelo Renato no Linkia.

Gotchas GHL serverless (ver ghl_integration_gotchas.md):
  - sempre consumir body do fetch (a gente ja consome via r.text).
  - dedupe 400: usar contactId do erro (nao implementado aqui — cabe adicionar
    se comecar a bater 400 duplicate).
  - delay de indexacao de 30-90s: enviar mensagem logo apos criar contato
    pode falhar. Contatos ja existem na lista antes do webhook.
"""

import logging
import os
import requests

log = logging.getLogger("ghl_client_medio_porte")

GHL_API_BASE = "https://services.leadconnectorhq.com"
GHL_API_VERSION = "2021-07-28"

# TODO Renato vai passar: PIPELINE_ID do Linkia para a campanha "PROSPECCAO
# ATIVA MEDIO PORTE SOROCABA". Enquanto nao houver, o move_opportunity_stage
# vai falhar com missing_pipeline_id — nao quebra o fluxo, so nao move card.
DEFAULT_PIPELINE_ID = os.getenv("LINKIA_PIPELINE_ID_MEDIO_PORTE", "").strip()

# Header obrigatorio pra escapar do bloqueio 1010 do Cloudflare no GHL.
USER_AGENT = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
)


def _base_headers(token: str) -> dict[str, str]:
    return {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Version": GHL_API_VERSION,
        "User-Agent": USER_AGENT,
    }


def send_whatsapp_message(
    contact_id: str,
    message: str,
    token: str,
    conversation_id: str | None = None,
) -> tuple[bool, int, str]:
    """
    Envia mensagem WhatsApp para o contato via API do GHL/Linkia.
    Retorna (ok, status_code, body).
    """
    url = f"{GHL_API_BASE}/conversations/messages"
    headers = _base_headers(token)
    payload = {
        "type": "WhatsApp",
        "contactId": contact_id,
        "message": message,
    }
    if conversation_id:
        payload["conversationId"] = conversation_id

    try:
        r = requests.post(url, json=payload, headers=headers, timeout=30)
        ok = r.ok
        if not ok:
            log.warning(
                "GHL send failed contact=%s status=%s body=%s",
                contact_id, r.status_code, r.text[:400],
            )
        else:
            log.info("GHL send ok contact=%s status=%s", contact_id, r.status_code)
        return ok, r.status_code, r.text
    except requests.RequestException as e:
        log.exception("GHL send exception: %s", e)
        return False, 0, str(e)


def move_opportunity_stage(
    opportunity_id: str,
    stage_id: str | None,
    token: str,
    status: str | None = None,
    pipeline_id: str | None = None,
) -> tuple[bool, int, str]:
    """
    Move card de oportunidade para uma etapa e/ou atualiza status via API v2 do GHL.

    - Se `stage_id` for informado, envia `pipelineStageId` no body (a API exige
      tambem `pipelineId`; usa `pipeline_id` recebido ou o DEFAULT_PIPELINE_ID).
    - Se `status` for informado (ex.: 'lost', 'won'), envia `status` no body.
    - Se ambos forem informados, envia num unico PUT.
    - Se nenhum for informado, nao chama a API e retorna (False, 0, 'noop').

    Retorna (ok, status_code, body).
    """
    if not opportunity_id:
        return False, 0, "missing_opportunity_id"
    if not token:
        return False, 0, "missing_token"

    payload: dict[str, str] = {}
    if stage_id:
        effective_pipeline = pipeline_id or DEFAULT_PIPELINE_ID
        if not effective_pipeline:
            return False, 0, "missing_pipeline_id"
        payload["pipelineStageId"] = stage_id
        payload["pipelineId"] = effective_pipeline
    if status:
        payload["status"] = status

    if not payload:
        return False, 0, "noop"

    url = f"{GHL_API_BASE}/opportunities/{opportunity_id}"
    headers = _base_headers(token)

    try:
        r = requests.put(url, json=payload, headers=headers, timeout=30)
        ok = r.ok
        if not ok:
            log.warning(
                "GHL move opportunity failed opp=%s payload=%s status=%s body=%s",
                opportunity_id, payload, r.status_code, r.text[:400],
            )
        else:
            log.info(
                "GHL move opportunity ok opp=%s payload=%s status=%s",
                opportunity_id, payload, r.status_code,
            )
        return ok, r.status_code, r.text
    except requests.RequestException as e:
        log.exception("GHL move opportunity exception opp=%s: %s", opportunity_id, e)
        return False, 0, str(e)
