#!/usr/bin/env python3
"""
scraper_idpj_trabalhista.py — SAVE Company / Cristiano Vasconcelos

Coleta decisões de TRTs em que o INCIDENTE DE DESCONSIDERAÇÃO DA PERSONALIDADE
JURÍDICA (IDPJ) foi NEGADO em execução trabalhista — ou seja, casos em que a
Justiça do Trabalho tentou (a pedido do empregado/credor) atingir o patrimônio
pessoal do sócio para pagar dívida trabalhista da empresa, e o sócio/empresa
se defendeu com sucesso (patrimônio pessoal protegido).

Ângulo editorial: NÃO é compliance de RH do dia a dia — é ameaça patrimonial
existencial ao sócio/empresário, a escala que conecta com o ICP de R$10-20M/ano.

Códigos DataJud verificados em campo (TRT2, junho/2026):
  classe.codigo = 12119  → "Incidente de Desconsideração de Personalidade Jurídica"
  movimentos.codigo = 220 → Improcedência (IDPJ NEGADO — sócio protegido — ALTA confiança)
  movimentos.codigo = 459 → Extinção sem Resolução do Mérito (sócio não alcançado,
                             mas por motivo processual, não de mérito — BAIXA confiança,
                             marcar para verificação manual antes de uso em conteúdo)

IMPORTANTE — valor da causa:
  O campo `valorCausa` NÃO está disponível na API pública do DataJud (testado e
  confirmado ausente no payload). Para os casos selecionados editorialmente, o
  valor da causa precisa ser buscado manualmente no PJe/tribunal de origem —
  pode não estar disponível publicamente (mesma limitação já registrada no
  pilar trabalhista existente).

Escopo: TRT1 a TRT24. Filtro de recência: dataHoraUltimaAtualizacao dentro dos
últimos 3 anos (decisão precisa ser recente; ajuizamento pode ser mais antigo —
duração do processo é parte do conteúdo).
"""
import json
import time
import requests
from pathlib import Path
from datetime import datetime, timedelta, timezone

OUTPUT = Path("/home/cristiano/meus-projetos/pesquisa-juridica/idpj_trabalhista_socio_protegido.json")
LOG    = Path("/home/cristiano/meus-projetos/pesquisa-juridica/idpj_trabalhista_run.log")

DATAJUD_KEY = "cDZHYzlZa0JadVREZDJCendQbXY6SkJlTzNjLV9TRENyQk1RdnFKZGRQdw=="
BASE = "https://api-publica.datajud.cnj.jus.br"
HEADERS = {"Authorization": f"APIKey {DATAJUD_KEY}", "Content-Type": "application/json"}

TRTS = {f"TRT{i}": f"api_publica_trt{i}" for i in range(1, 25)}

CLASSE_IDPJ = 12119
MOV_NEGADO_ALTA = 220   # Improcedência — sócio protegido, mérito
MOV_NEGADO_BAIXA = 459  # Extinção sem Resolução do Mérito — verificar manualmente

DATA_INICIO = (datetime.now(timezone.utc) - timedelta(days=3 * 365)).strftime("%Y-%m-%d")

PAGE_SIZE = 100
MAX_PAGES = 100  # 10.000 registros/tribunal — limite do Elasticsearch


def log(msg: str):
    ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    line = f"[{ts}] {msg}"
    print(line)
    with open(LOG, "a") as f:
        f.write(line + "\n")


def buscar_tribunal(endpoint: str, sigla: str, existentes: set) -> list:
    resultados = []
    for offset in range(0, PAGE_SIZE * MAX_PAGES, PAGE_SIZE):
        query = {
            "size": PAGE_SIZE,
            "from": offset,
            "query": {
                "bool": {
                    "must": [
                        {"term": {"classe.codigo": CLASSE_IDPJ}},
                        {"terms": {"movimentos.codigo": [MOV_NEGADO_ALTA, MOV_NEGADO_BAIXA]}},
                        {"range": {"dataHoraUltimaAtualizacao": {"gte": DATA_INICIO}}},
                    ]
                }
            },
            "_source": [
                "numeroProcesso", "classe", "assuntos", "movimentos",
                "orgaoJulgador", "dataAjuizamento", "dataHoraUltimaAtualizacao",
                "tribunal", "grau",
            ],
            "sort": [{"dataHoraUltimaAtualizacao": {"order": "desc"}}],
        }
        url = f"{BASE}/{endpoint}/_search"
        for tentativa in range(3):
            try:
                r = requests.post(url, headers=HEADERS, json=query, timeout=30)
                break
            except requests.exceptions.RequestException as e:
                log(f"  {sigla} | erro tentativa {tentativa+1}: {e}")
                time.sleep(2)
        else:
            log(f"  {sigla} | falhou após 3 tentativas, offset {offset}")
            break

        if r.status_code != 200:
            log(f"  {sigla} | HTTP {r.status_code} offset {offset}: {r.text[:200]}")
            break

        hits = r.json().get("hits", {}).get("hits", [])
        if not hits:
            break

        for h in hits:
            src = h["_source"]
            num = src.get("numeroProcesso")
            if not num or num in existentes:
                continue
            existentes.add(num)

            movs_codigos = {m.get("codigo") for m in src.get("movimentos", []) if isinstance(m, dict)}
            confianca = "alta" if MOV_NEGADO_ALTA in movs_codigos else "baixa_verificar"

            resultados.append({
                "numero": num,
                "tribunal": sigla,
                "grau": src.get("grau"),
                "classe": src.get("classe"),
                "orgao_julgador": src.get("orgaoJulgador", {}).get("nome") if isinstance(src.get("orgaoJulgador"), dict) else src.get("orgaoJulgador"),
                "data_ajuizamento": src.get("dataAjuizamento"),
                "ultima_atualizacao": src.get("dataHoraUltimaAtualizacao"),
                "assuntos": [a.get("nome") for a in src.get("assuntos", []) if isinstance(a, dict)],
                "movimentos_codigos": sorted(movs_codigos),
                "confianca_vitoria": confianca,
                "resultado": "socio_protegido_idpj_negado",
            })

        log(f"  {sigla} | offset {offset} | +{len(hits)} hits | total acumulado {len(resultados)}")

        if len(hits) < PAGE_SIZE:
            break

    return resultados


def main():
    log("=== INÍCIO scraper_idpj_trabalhista ===")
    log(f"Filtro de recência: dataHoraUltimaAtualizacao >= {DATA_INICIO}")

    todos = []
    existentes = set()

    if OUTPUT.exists():
        try:
            todos = json.loads(OUTPUT.read_text())
            existentes = {d["numero"] for d in todos}
            log(f"Carregado output existente: {len(todos)} casos")
        except Exception as e:
            log(f"Não foi possível carregar output existente: {e}")

    for sigla, endpoint in TRTS.items():
        log(f"--- {sigla} ({endpoint}) ---")
        try:
            novos = buscar_tribunal(endpoint, sigla, existentes)
            todos.extend(novos)
            log(f"{sigla} concluído: +{len(novos)} casos novos | total geral {len(todos)}")
        except Exception as e:
            log(f"{sigla} ERRO GERAL: {e}")
        OUTPUT.write_text(json.dumps(todos, ensure_ascii=False, indent=2))
        time.sleep(1)

    log(f"=== FIM. Total: {len(todos)} casos salvos em {OUTPUT} ===")
    alta = sum(1 for d in todos if d["confianca_vitoria"] == "alta")
    baixa = len(todos) - alta
    log(f"Confiança alta (Improcedência/220): {alta} | Confiança baixa (Extinção/459, verificar): {baixa}")


if __name__ == "__main__":
    main()
