#!/usr/bin/env python3
"""
Valida e filtra lista de contatos PX3 Lab para WhatsApp.
Sem necessidade de conexão ativa - valida por formato E164 brasileiro.
"""
import csv
import re
import json
from datetime import datetime

INPUT = "/opt/mia/workspace/clientes/px3lab/lista_contatos_whatsapp.csv"
OUTPUT_VALIDOS = "/opt/mia/workspace/clientes/px3lab/contatos_whatsapp_validos.csv"
OUTPUT_INVALIDOS = "/opt/mia/workspace/clientes/px3lab/contatos_whatsapp_invalidos.csv"
RELATORIO = "/opt/mia/workspace/clientes/px3lab/relatorio_validacao.json"

# DDDs válidos no Brasil
DDDS_VALIDOS = {
    11,12,13,14,15,16,17,18,19,  # SP
    21,22,24,  # RJ
    27,28,  # ES
    31,32,33,34,35,37,38,  # MG
    41,42,43,44,45,46,  # PR
    47,48,49,  # SC
    51,53,54,55,  # RS
    61,62,64,  # GO/DF
    63,  # TO
    65,66,  # MT
    67,  # MS
    68,  # AC
    69,  # RO
    71,73,74,75,77,  # BA
    79,  # SE
    81,87,  # PE
    82,  # AL
    83,  # PB
    84,  # RN
    85,88,  # CE
    86,89,  # PI
    91,93,94,  # PA
    92,97,  # AM
    95,  # RR
    96,  # AP
    98,99,  # MA
}

BOT_EMAIL_DOMAINS = {
    'gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com',
    'icloud.com', 'me.com', 'mac.com', 'live.com'
}

def normalize_phone(phone: str) -> str:
    """Remove tudo exceto + e dígitos."""
    phone = phone.strip()
    digits_only = re.sub(r'[^\d+]', '', phone)
    return digits_only

def classify_br_mobile(phone: str) -> tuple[bool, str]:
    """
    Retorna (is_valid, reason).
    Número BR mobile válido: +55 + DDD (2 dígitos) + 9 (prefixo móvel) + 8 dígitos = 14 dígitos total
    """
    if not phone.startswith('+55'):
        return False, "não é BR"

    digits = phone[3:]  # remove +55

    if len(digits) == 11:
        ddd = int(digits[:2])
        prefix = digits[2]
        if ddd not in DDDS_VALIDOS:
            return False, f"DDD inválido: {ddd}"
        if prefix != '9':
            return False, f"não é celular (prefixo {prefix})"
        return True, "celular BR válido"

    elif len(digits) == 10:
        # Pode ser fixo ou celular antigo (sem 9º dígito)
        ddd = int(digits[:2])
        if ddd not in DDDS_VALIDOS:
            return False, f"DDD inválido: {ddd}"
        # Adiciona 9 para celular
        return False, "celular sem 9º dígito - formato antigo"

    else:
        return False, f"tamanho inválido: {len(digits)} dígitos"

def has_bot_name(name: str) -> bool:
    name = name.strip().lower()
    if name in ('none none', 'none', ''):
        return True
    parts = name.split()
    if len(parts) == 1 and len(parts[0]) > 15:
        return True
    return False

def is_us_bot(phone: str) -> bool:
    return phone.startswith('+1')

def main():
    with open(INPUT, encoding='utf-8') as f:
        reader = csv.DictReader(f)
        rows = list(reader)

    validos = []
    invalidos = []
    stats = {
        "total": len(rows),
        "validos": 0,
        "invalidos_br_formato": 0,
        "invalidos_eua_bot": 0,
        "invalidos_outros_pais": 0,
        "invalidos_nome_bot": 0,
        "processado_em": datetime.now().isoformat()
    }

    for row in rows:
        phone_raw = row.get('Telefone', '').strip()
        nome = row.get('Nome', '').strip()
        phone = normalize_phone(phone_raw)

        motivo_invalido = None

        if is_us_bot(phone):
            motivo_invalido = "número EUA (+1) - possível bot"
            stats["invalidos_eua_bot"] += 1
        elif not phone.startswith('+55'):
            motivo_invalido = f"país não-BR: {phone[:3] if len(phone) >= 3 else phone}"
            stats["invalidos_outros_pais"] += 1
        else:
            is_valid, reason = classify_br_mobile(phone)
            if not is_valid:
                motivo_invalido = reason
                stats["invalidos_br_formato"] += 1
            elif has_bot_name(nome):
                # Número válido mas sem nome - inclui como válido com flag
                stats["sem_nome"] = stats.get("sem_nome", 0) + 1
                row['Nome'] = "(sem nome)"

        row['Telefone_normalizado'] = phone

        if motivo_invalido:
            row['motivo_invalido'] = motivo_invalido
            invalidos.append(row)
        else:
            validos.append(row)
            stats["validos"] += 1

    # Escreve válidos
    if validos:
        fieldnames = list(validos[0].keys())
        with open(OUTPUT_VALIDOS, 'w', newline='', encoding='utf-8') as f:
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(validos)

    # Escreve inválidos
    if invalidos:
        fieldnames = list(invalidos[0].keys())
        with open(OUTPUT_INVALIDOS, 'w', newline='', encoding='utf-8') as f:
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(invalidos)

    with open(RELATORIO, 'w') as f:
        json.dump(stats, f, indent=2, ensure_ascii=False)

    print(json.dumps(stats, indent=2, ensure_ascii=False))
    print(f"\nArquivos gerados:")
    print(f"  Válidos:   {OUTPUT_VALIDOS}")
    print(f"  Inválidos: {OUTPUT_INVALIDOS}")

if __name__ == '__main__':
    main()
