#!/usr/bin/env python3
"""
scraper_execucao_v2.py — FRENTE 6: Execução e Localização de Bens
Usa BrightData (web_unlocker) para raspar decisões reais do STJ (scon.stj.jus.br)
sobre tentativas de ocultação de bens, fraude à execução, desconsideração
da personalidade jurídica, penhora de cônjuge, dissolução irregular, etc.

Editorial: engenharia reversa → o que o ICP deve fazer PREVENTIVAMENTE.
"""

import json, time, re, os
from pathlib import Path
from dotenv import load_dotenv
import requests

load_dotenv(os.path.expanduser("~/meus-projetos/.env"))

BD_KEY  = os.getenv("BRIGHTDATA_API_KEY", "")
BASE    = Path(__file__).parent
OUT     = BASE / "decisoes_execucao.json"

# STJ pesquisa de jurisprudência (retorna JSON serializado)
STJ_API = "https://scon.stj.jus.br/SCON/jurisprudencia/toc.jsp"

BUSCAS = [
    {
        "tema":   "fraude_execucao",
        "label":  "Fraude à Execução — Alienação Após Citação",
        "query":  "fraude execução alienação imóvel devedor citado",
        "editorial": {
            "o_que_aconteceu": "Devedor alienou bem imóvel após ser citado em processo de execução. O bem já havia sido transferido para terceiro, mas o credor questionou a validade do negócio.",
            "como_foi_encontrado": "O credor consultou a matrícula do imóvel no cartório, identificou a data da transferência e cruzou com a data da citação. SISBAJUD confirmou ausência de liquidez nas contas.",
            "o_que_o_tribunal_decidiu": "Transferência declarada ineficaz. O bem voltou à execução como se nunca tivesse saído. O adquirente perdeu o bem e ainda responde por má-fé.",
            "conduta_preventiva": [
                "Mantenha contabilidade separada entre PF e PJ — mistura cria vulnerabilidade",
                "Nunca transfira bens após receber qualquer notificação ou citação judicial",
                "Guarde todos os contratos de compra e venda com data anterior à dívida",
                "Qualquer planejamento patrimonial legítimo deve ser feito ANTES de qualquer processo",
                "Holding patrimonial estruturada com antecedência é válida — criada durante crise, não é",
            ],
        }
    },
    {
        "tema":   "desconsideracao_personalidade",
        "label":  "Patrimônio do Sócio Alcançado — Confusão Patrimonial",
        "query":  "desconsideração personalidade jurídica confusão patrimonial sócio penhora",
        "editorial": {
            "o_que_aconteceu": "Empresa devedora não tinha bens suficientes. Credor pediu desconsideração para atingir patrimônio pessoal do sócio.",
            "como_foi_encontrado": "Perito identificou mistura de contas PJ e PF, pagamentos pessoais feitos com CNPJ, imóveis pessoais financiados por receita da empresa e ausência de contratos formais entre sócios.",
            "o_que_o_tribunal_decidiu": "Desconsideração deferida. Sócio teve bloqueio de conta pessoal, imóvel residencial incluído na penhora e veículos em seu nome constritos.",
            "conduta_preventiva": [
                "Nunca pague despesas pessoais com conta PJ — isso é confusão patrimonial",
                "Formalize contratos de mútuo entre sócio e empresa se precisar usar recursos",
                "Pró-labore deve ser pago regularmente e documentado em folha",
                "Registre em ata toda decisão relevante da empresa — reuniões, investimentos, distribuição",
                "Mantenha contabilidade rigorosa com balanços anuais assinados por contador habilitado",
            ],
        }
    },
    {
        "tema":   "penhora_conjuge",
        "label":  "Meação do Cônjuge Atingida por Dívida do Sócio",
        "query":  "penhora meação cônjuge devedor dívida empresarial bloqueio bens",
        "editorial": {
            "o_que_aconteceu": "Sócio de empresa com dívidas teve bens bloqueados junto com a meação da cônjuge — que alegava não participar da empresa.",
            "como_foi_encontrado": "Credor consultou RENAJUD (veículos), cartório de imóveis e CCS do Bacen. Identificou bens no nome do casal. Juiz bloqueou a meação por entender que beneficiou da atividade empresarial.",
            "o_que_o_tribunal_decidiu": "Penhora da meação mantida. Para o cônjuge liberar sua parte, teve que comprovar que os bens eram anteriores ao casamento ou adquiridos com recursos comprovadamente próprios.",
            "conduta_preventiva": [
                "Documente a origem de cada bem relevante — de onde veio o recurso da compra",
                "Pacto antenupcial pode separar patrimônios — mas deve ser feito antes de qualquer dívida",
                "Cônjuge que não é sócio deve ter declaração de IR individual e separada",
                "Guarde comprovante de aquisição de bens com data e origem dos recursos",
                "Bens recebidos por herança ou doação devem ter documentação clara de origem",
            ],
        }
    },
    {
        "tema":   "bem_familia_excecao",
        "label":  "Bem de Família Não Protegido — Exceções à Lei 8.009/90",
        "query":  "bem família impenhorável exceção penhora fiador aval dívida",
        "editorial": {
            "o_que_aconteceu": "Devedor alegou que seu imóvel residencial era bem de família e não poderia ser penhorado. O credor contestou e o juiz deferiu a penhora.",
            "como_foi_encontrado": "Credor demonstrou que o bem não era o único imóvel, ou que havia dívida de condomínio/IPTU, ou que o sócio havia dado o imóvel como garantia, ou que o bem não servia de residência efetiva.",
            "o_que_o_tribunal_decidiu": "Penhora mantida. A impenhorabilidade do bem de família tem exceções: fiador em contrato de locação, dívida de condomínio, hipoteca para aquisição do próprio bem, entre outras.",
            "conduta_preventiva": [
                "Nunca assine como fiador ou avalista usando o imóvel residencial como garantia",
                "Mantenha IPTU e condomínio em dia — dívidas sobre o imóvel rompem a proteção",
                "O bem de família deve ser o imóvel de residência efetiva — documente com contas no endereço",
                "Empresário com múltiplos imóveis: apenas o de menor valor protege como bem de família",
                "Holding imobiliária estruturada previamente pode proteger patrimônio de forma legítima",
            ],
        }
    },
    {
        "tema":   "dissolucao_irregular",
        "label":  "Dissolução Irregular — Sócio Responde Pessoalmente",
        "query":  "dissolução irregular sociedade sócio responsabilidade pessoal execução dívida",
        "editorial": {
            "o_que_aconteceu": "Empresa parou de funcionar sem baixa formal. Endereço desatualizado, CNPJ ativo mas inativo na prática. Credor redirecionou a execução para os sócios pessoalmente.",
            "como_foi_encontrado": "Oficial de Justiça não encontrou a empresa no endereço cadastrado. Certidão de dissolução irregular. SISBAJUD não encontrou saldo. Credor pediu desconsideração com base na dissolução irregular.",
            "o_que_o_tribunal_decidiu": "Redirecionamento autorizado. Sócios passaram a responder pessoalmente pela dívida da empresa, incluindo com patrimônio residencial.",
            "conduta_preventiva": [
                "Se a empresa vai encerrar, faça a baixa formal antes — distrato ou dissolução registrada",
                "Mantenha endereço atualizado na Junta Comercial e na Receita Federal",
                "Empresa inativa deve ter declaração de inatividade entregue anualmente",
                "Guarde comprovante de todas as comunicações formais de encerramento",
                "Antes de encerrar: quite ou negocie todas as dívidas registradas — elas não somem com o CNPJ",
            ],
        }
    },
    {
        "tema":   "sisbajud_renajud",
        "label":  "SISBAJUD/RENAJUD — Bloqueio Automático de Bens",
        "query":  "SISBAJUD penhora online conta bancária execução bloqueio RENAJUD veículo",
        "editorial": {
            "o_que_aconteceu": "Devedor tinha dívida em execução. Juiz expediu ordem via SISBAJUD. Em segundos, contas em todos os bancos foram bloqueadas. RENAJUD restringiu os veículos no mesmo dia.",
            "como_foi_encontrado": "Sistemas automáticos do Judiciário (SISBAJUD para contas, RENAJUD para veículos, CNIB para imóveis) operam em tempo real e cobrem 100% das instituições financeiras brasileiras.",
            "o_que_o_tribunal_decidiu": "Bloqueios mantidos. Para desbloqueio, devedor precisou provar depósito ou garantia equivalente à dívida, ou que os bens eram impenhoráveis por lei.",
            "conduta_preventiva": [
                "Caixa operacional da empresa deve estar em conta separada da reserva estratégica",
                "Mantenha comprovante de que valores em conta são de terceiros ou com destinação específica",
                "Salário de funcionários não pode ser bloqueado — mas deve estar em conta separada",
                "Impenhorabilidade de bens específicos (salário PF, FGTS) deve ser requerida imediatamente",
                "Ao primeiro sinal de processo em execução: consulte advogado antes que o bloqueio chegue",
            ],
        }
    },
    {
        "tema":   "fraude_credores_pauliana",
        "label":  "Fraude Contra Credores — Anulação de Alienação Antes do Processo",
        "query":  "fraude credores ação pauliana anulação alienação insolvência devedor",
        "editorial": {
            "o_que_aconteceu": "Devedor transferiu bens antes do processo judicial (quando ainda não havia citação). Credor entrou com ação pauliana para anular a alienação.",
            "como_foi_encontrado": "Credor provou que na época da transferência o devedor já estava insolvente (devia mais do que tinha). Pesquisa patrimonial histórica no cartório revelou que o bem foi o último ativo transferido.",
            "o_que_o_tribunal_decidiu": "Alienação anulada retroativamente. O bem voltou ao patrimônio do devedor para pagamento da dívida. Terceiro adquirente perdeu o bem.",
            "conduta_preventiva": [
                "Qualquer transferência de bem feita enquanto existe dívida relevante pode ser questionada",
                "Mantenha balanço patrimonial atualizado — prova que a empresa não estava insolvente na época",
                "Doação de bens para filhos/cônjuge com dívida ativa é especialmente vulnerável à pauliana",
                "Transação legítima deve ter preço de mercado e pagamento documentado — não pode ser simulação",
                "O critério é a data da dívida, não a data do processo — dívida antiga protege menos do que parece",
            ],
        }
    },
    {
        "tema":   "extensao_falencia",
        "label":  "Falência Estendida / Consolidação Patrimonial de Grupo",
        "query":  "extensão falência grupo econômico consolidação patrimonial confusão sociedades",
        "editorial": {
            "o_que_aconteceu": "Empresa faliu. Credor pediu extensão da falência para outras empresas do mesmo grupo, argumentando que eram a mesma coisa com CNPJs diferentes.",
            "como_foi_encontrado": "Investigação revelou: mesmo endereço, mesmos sócios, recursos misturados, uma empresa pagando despesas da outra sem contrato, marca e funcionários compartilhados sem formalização.",
            "o_que_o_tribunal_decidiu": "Extensão deferida parcialmente. Empresas com operação independente comprovada foram poupadas. As que tinham confusão patrimonial real foram incluídas na massa falida.",
            "conduta_preventiva": [
                "Grupo econômico legítimo: cada empresa tem CNPJ, conta, contabilidade e contrato próprios",
                "Serviços entre empresas do grupo devem ter contratos formais com preços de mercado",
                "Nunca use uma empresa para pagar despesas de outra sem contrato de mútuo ou prestação de serviços",
                "Cada empresa do grupo deve ter reuniões e atas independentes — decida e registre separado",
                "Holding estruturada previamente com contratos formais é o instrumento legítimo de gestão de grupo",
            ],
        }
    },
    {
        "tema":   "transferencia_terceiro",
        "label":  "Transferência para Familiar / Laranja — Simulação Detectada",
        "query":  "fraude execução transferência imóvel terceiro familiar simulação devedor nulo",
        "editorial": {
            "o_que_aconteceu": "Devedor transferiu imóvel para filho, cônjuge ou sócio por preço simbólico ou sem contrapartida real. Credor questionou a autenticidade do negócio.",
            "como_foi_encontrado": "Pesquisa patrimonial cruzou: data de aquisição, vínculo familiar, valor da transação vs. valor de mercado, declaração de IR dos envolvidos, e CCS do Bacen para verificar se houve pagamento real.",
            "o_que_o_tribunal_decidiu": "Transferência declarada simulação — nula de pleno direito. Bem retornou à penhora. Todos os envolvidos (devedor e adquirente) responderam por má-fé processual.",
            "conduta_preventiva": [
                "Transações entre familiares devem ter preço de mercado — avaliação documentada é essencial",
                "Pagamento precisa ser real e rastreável — TED/PIX com extrato, nunca 'pagamento em espécie'",
                "Doações formais têm limite legal e devem ser declaradas no IR de todos os envolvidos",
                "O vínculo familiar entre comprador e vendedor não invalida a transação — mas aumenta o escrutínio",
                "Holding familiar estruturada com advogado, antes de qualquer processo, é o caminho correto",
            ],
        }
    },
    {
        "tema":   "bem_familia_socio",
        "label":  "Imóvel Residencial do Sócio Penhorado por Dívida da Empresa",
        "query":  "penhora imóvel residencial sócio dívida empresa execução bem família sócio",
        "editorial": {
            "o_que_aconteceu": "Sócio de empresa devedora teve seu imóvel residencial penhorado. Alegou ser bem de família. Credor demonstrou que o sócio tinha responsabilidade pessoal pela dívida.",
            "como_foi_encontrado": "Credor demonstrou dissolução irregular da empresa, ou confusão patrimonial, ou que o sócio tinha dado aval pessoal no contrato original.",
            "o_que_o_tribunal_decidiu": "Penhora mantida nos casos em que a responsabilidade pessoal do sócio estava configurada. Bem de família não protege quando a dívida é do próprio proprietário com responsabilidade pessoal.",
            "conduta_preventiva": [
                "Nunca assine aval pessoal em contratos da empresa sem entender o alcance — inclui seu imóvel",
                "Distinga claramente sua responsabilidade como sócio (limitada ao capital) da responsabilidade como avalista (ilimitada)",
                "Contratos bancários da empresa quase sempre exigem aval pessoal do sócio — isso expõe seu patrimônio",
                "Negocie retirada do aval pessoal ao renegociar dívida — é item de negociação válido",
                "Empresa regularmente constituída e documentada protege o sócio — empresa bagunçada expõe tudo",
            ],
        }
    },
]

HEADERS_BD = {
    "Authorization": f"Bearer {BD_KEY}",
    "Content-Type": "application/json"
}

def fetch_brightdata(url: str) -> str:
    payload = {
        "zone": "web_unlocker1",
        "url": url,
        "format": "raw"
    }
    r = requests.post(
        "https://api.brightdata.com/request",
        headers=HEADERS_BD,
        json=payload,
        timeout=60
    )
    return r.text

def buscar_stj(query: str, max_resultados: int = 5) -> list:
    """Busca no STJ pesquisa de jurisprudência e retorna lista de casos."""
    query_encoded = query.replace(" ", "+")
    url = (
        f"https://scon.stj.jus.br/SCON/pesquisar.jsp"
        f"?newsession=yes&tipo_visualizacao=RESUMO&b=ACOR"
        f"&livre={query_encoded}"
        f"&thesaurus=JURIDICO&p=true"
        f"&dataInicio=01%2F01%2F2023"
        f"&operador=e&l={max_resultados}&i=1"
    )
    try:
        html = fetch_brightdata(url)
        return extrair_decisoes_stj(html)
    except Exception as e:
        print(f"  ✗ BrightData erro: {e}")
        return []

def extrair_decisoes_stj(html: str) -> list:
    """Extrai dados das decisões do HTML do STJ."""
    decisoes = []
    # Extrai blocos de cada acórdão
    blocos = re.findall(
        r'<div[^>]*class="[^"]*documento[^"]*"[^>]*>(.*?)</div>\s*</div>',
        html, re.S | re.I
    )
    if not blocos:
        # fallback: procura por padrões de número de processo
        numeros = re.findall(r'(REsp|AgInt|AREsp|EREsp)\s+[\d.,/]+', html)
        ementas  = re.findall(r'(?:EMENTA|Ementa)[:.\s]+(.*?)(?=<br|</p|EMENTA|Ementa|\Z)', html, re.S)
        datas    = re.findall(r'(\d{2}/\d{2}/\d{4})', html)
        for i, num in enumerate(numeros[:5]):
            ementa = ementas[i].strip()[:1200] if i < len(ementas) else ""
            ementa = re.sub(r'<[^>]+>', ' ', ementa).strip()
            ementa = re.sub(r'\s+', ' ', ementa)
            decisoes.append({
                "numero": num,
                "data": datas[i] if i < len(datas) else "",
                "ementa": ementa
            })
    return decisoes

def buscar_datajud_stj(query_text: str, assunto_codes: list = None) -> list:
    """Busca no DataJud STJ usando match na ementa."""
    url = "https://api-publica.datajud.cnj.jus.br/api_publica_stj/_search"
    headers = {
        "Authorization": "APIKey cDZHYzlZa0JadVREZDJCendQbXY6SkJlTzNjLV9TRENyQk1RdnFKZGRQdw==",
        "Content-Type": "application/json"
    }
    # Busca por palavras-chave na ementa
    palavras = query_text.split()[:4]  # Pega as 4 primeiras palavras relevantes
    body = {
        "size": 5,
        "query": {
            "bool": {
                "must": [
                    {"match": {"ementa": query_text}}
                ],
                "filter": [
                    {"range": {"dataJulgamento": {"gte": "2023-01-01", "lte": "2026-12-31"}}}
                ]
            }
        },
        "sort": [{"dataJulgamento": {"order": "desc"}}]
    }
    try:
        r = requests.post(url, headers=headers, json=body, timeout=25)
        if r.status_code != 200:
            return []
        hits = r.json().get("hits", {}).get("hits", [])
        resultados = []
        for h in hits:
            s = h["_source"]
            ementa = s.get("ementa", "")
            if len(ementa) > 80:
                resultados.append({
                    "numero": s.get("numeroProcesso", ""),
                    "data": (s.get("dataJulgamento") or "")[:10],
                    "ementa": ementa[:1500],
                    "tribunal": "STJ",
                    "orgao": s.get("orgaoJulgador", {}).get("nome", "") if isinstance(s.get("orgaoJulgador"), dict) else "",
                    "relator": s.get("relator", {}).get("nome", "") if isinstance(s.get("relator"), dict) else "",
                })
        return resultados
    except Exception as e:
        print(f"  ✗ DataJud STJ: {e}")
        return []

def buscar_datajud_tjs(query_text: str, tribunal: str) -> list:
    """Busca em tribunais estaduais com query simpler."""
    endpoint_map = {
        "TJSP": "api_publica_tjsp",
        "TJRJ": "api_publica_tjrj",
        "TJPR": "api_publica_tjpr",
        "TJSC": "api_publica_tjsc",
    }
    endpoint = endpoint_map.get(tribunal, f"api_publica_{tribunal.lower()}")
    url = f"https://api-publica.datajud.cnj.jus.br/{endpoint}/_search"
    headers = {
        "Authorization": "APIKey cDZHYzlZa0JadVREZDJCendQbXY6SkJlTzNjLV9TRENyQk1RdnFKZGRQdw==",
        "Content-Type": "application/json"
    }
    # Para TJs, busca por assunto codes relacionados a execução
    EXEC_ASSUNTOS = [
        10028,  # Contratos
        9999,   # Execução
        7697,   # Cédula
    ]
    EXEC_CLASSES = [
        12154,  # Execução de Título Extrajudicial (TJSP)
        7,      # Execução de Título Extrajudicial (STJ)
        198,    # Embargos à Execução
    ]
    body = {
        "size": 3,
        "query": {
            "bool": {
                "must": [
                    {"terms": {"classe.codigo": EXEC_CLASSES}}
                ],
                "filter": [
                    {"range": {"dataAjuizamento": {"gte": "2023-01-01"}}}
                ]
            }
        },
        "sort": [{"dataHoraUltimaAtualizacao": {"order": "desc"}}]
    }
    try:
        r = requests.post(url, headers=headers, json=body, timeout=20)
        if r.status_code != 200:
            return []
        hits = r.json().get("hits", {}).get("hits", [])
        resultados = []
        for h in hits:
            s = h["_source"]
            assuntos = s.get("assuntos", [])
            assunto_txt = " | ".join(a.get("nome", "") for a in assuntos if isinstance(a, dict))
            resultados.append({
                "numero": s.get("numeroProcesso", ""),
                "data": (s.get("dataAjuizamento") or "")[:10],
                "ementa": f"[{tribunal}] Execução — {assunto_txt}" if assunto_txt else f"[{tribunal}] Processo de execução",
                "tribunal": tribunal,
                "orgao": s.get("orgaoJulgador", {}).get("nome", "") if isinstance(s.get("orgaoJulgador"), dict) else "",
                "relator": "",
            })
        return resultados
    except Exception as e:
        return []

def main():
    print("=" * 65)
    print("  FRENTE 6 — EXECUÇÃO E LOCALIZAÇÃO DE BENS")
    print("  BrightData + DataJud STJ | 2023-2026")
    print("=" * 65)

    todos = []

    for busca in BUSCAS:
        tema  = busca["tema"]
        label = busca["label"]
        query = busca["query"]
        ed    = busca["editorial"]

        print(f"\n[{label}]")

        # Tenta DataJud STJ primeiro (mais rápido)
        stj_results = buscar_datajud_stj(query)
        print(f"  DataJud STJ: {len(stj_results)} decisões")

        # BrightData STJ para complementar
        bd_results = []
        if BD_KEY and len(stj_results) < 2:
            bd_results = buscar_stj(query, max_resultados=3)
            print(f"  BrightData STJ: {len(bd_results)} decisões")
            time.sleep(2)

        # Combina resultados
        combinados = stj_results + bd_results

        if combinados:
            melhor = combinados[0]
            entrada = {
                "tema":    tema,
                "label":   label,
                "tribunal": melhor.get("tribunal", "STJ"),
                "numero":  melhor.get("numero", ""),
                "data":    melhor.get("data", ""),
                "orgao":   melhor.get("orgao", ""),
                "relator": melhor.get("relator", ""),
                "ementa":  melhor.get("ementa", "")[:1500],
                "editorial": ed,
                "total_encontrados": len(combinados),
            }
        else:
            # Sem resultado da API — usa dado editorial estruturado
            entrada = {
                "tema":    tema,
                "label":   label,
                "tribunal": "STJ",
                "numero":  "",
                "data":    "",
                "orgao":   "",
                "relator": "",
                "ementa":  "",
                "editorial": ed,
                "total_encontrados": 0,
            }

        todos.append(entrada)
        print(f"  ✓ {label}: {len(combinados)} resultado(s)")
        time.sleep(1)

    OUT.write_text(json.dumps(todos, ensure_ascii=False, indent=2), encoding="utf-8")
    print(f"\n{'='*65}")
    print(f"  Total de temas processados: {len(todos)}")
    print(f"  Salvo em: {OUT}")
    print("=" * 65)

if __name__ == "__main__":
    main()
