#!/usr/bin/env python3
"""
Enviador CLI - Envia emails direto via Postfix (SEM AJAX/Web)
Muito mais rápido que a interface web!

Uso: python3 enviador_cli.py [--batch 50] [--delay 100] [--start 0]
"""

import os
import sys
import time
import random
import string
import re
import glob
from datetime import datetime
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import formataddr, formatdate, make_msgid
import smtplib
import argparse

# ============================================================================
# CONFIGURAÇÕES
# ============================================================================

os.chdir('/var/www/html')  # Garante que tá em /var/www/html

DOMINIO = "mail.appwhatsapconnect.com"
NUM_USUARIOS = 4000
VALOR_BASE = 2740.38
VALOR_MIN_PERCENT = 0.85
VALOR_MAX_PERCENT = 1.15

SMTP_HOST = "localhost"
SMTP_PORT = 25

PASTA_HTML = "/var/www/html/Eng"
ARQUIVO_EMAILS = "/var/www/html/emails.txt"
ARQUIVO_ASSUNTOS = "/var/www/html/assuntos.txt"
ARQUIVO_REMETENTES = "/var/www/html/remetentes.txt"
ARQUIVO_LINKS = "/var/www/html/Links.txt"

# ============================================================================
# CORES
# ============================================================================

class Colors:
    RESET = '\033[0m'
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    BLUE = '\033[94m'
    CYAN = '\033[96m'

# ============================================================================
# FUNÇÕES AUXILIARES
# ============================================================================

def extrair_nome(email):
    try:
        local = email.split('@')[0]
        local = re.sub(r'\d+$', '', local)
        nome = local.replace('.', ' ').replace('_', ' ').replace('-', ' ')
        return ' '.join(word.capitalize() for word in nome.split()) or "Cliente"
    except:
        return "Cliente"

def get_domain(email):
    try:
        return email.split('@')[1]
    except:
        return 'localhost'

def gerar_numero(length=7):
    return ''.join(str(random.randint(0, 9)) for _ in range(length))

def gerar_pros():
    numero = gerar_numero(7)
    sufixo = random.randint(0, 9)
    return f"PROS{numero}-{sufixo}"

def gerar_valor(base=2740.38, min_pct=0.85, max_pct=1.15):
    v_min = base * min_pct
    v_max = base * max_pct
    valor = random.uniform(v_min, v_max)
    return f"{valor:,.2f}".replace(',', 'X').replace('.', ',').replace('X', '.')

def aplicar_spintax(text):
    pattern = r'\{([^{}]*\|[^{}]*)\}'
    while re.search(pattern, text):
        def resolver(m):
            opcoes = m.group(1).split('|')
            return random.choice(opcoes).strip()
        text = re.sub(pattern, resolver, text)
    return text

def replace_numero(text):
    def repl(m):
        length = int(m.group(1))
        return ''.join(str(random.randint(0, 9)) for _ in range(length))
    return re.sub(r'\{numero-(\d+)\}', repl, text)

def replace_random(text):
    def repl(m):
        length = int(m.group(1))
        chars = string.ascii_uppercase + string.digits
        return ''.join(random.choice(chars) for _ in range(length))
    return re.sub(r'\{random-(\d+)\}', repl, text)

# ============================================================================
# CARREGAR ARQUIVOS
# ============================================================================

def carregar_htmls():
    htmls = []
    possibilidades = ['Eng', 'eng', './Eng', './eng', '/tmp/Eng', '/tmp/eng']

    for pasta in possibilidades:
        if os.path.isdir(pasta):
            PASTA_HTML = pasta
            break

    if os.path.isdir(PASTA_HTML):
        arquivos = sorted(glob.glob(f"{PASTA_HTML}/*.html"))
        for arquivo in arquivos:
            try:
                with open(arquivo, 'r', encoding='utf-8') as f:
                    htmls.append(f.read())
            except:
                pass

    print(f"DEBUG: Procurando em '{PASTA_HTML}', encontrados {len(arquivos)} arquivos")
    return htmls

def carregar_emails():
    emails = []
    if os.path.exists(ARQUIVO_EMAILS):
        with open(ARQUIVO_EMAILS, 'r', encoding='utf-8') as f:
            emails = [e.strip() for e in f if e.strip() and '@' in e]
    print(f"DEBUG: Primeiros 5 emails carregados: {emails[:5]}")
    return emails

def carregar_assuntos():
    if os.path.exists(ARQUIVO_ASSUNTOS):
        with open(ARQUIVO_ASSUNTOS, 'r', encoding='utf-8') as f:
            conteudo = f.read().strip()
        if '|' in conteudo:
            return [conteudo]  # Uma linha com spintax
        else:
            return [l.strip() for l in conteudo.split('\n') if l.strip()]
    return ["Asunto"]

def carregar_remetentes():
    if os.path.exists(ARQUIVO_REMETENTES):
        with open(ARQUIVO_REMETENTES, 'r', encoding='utf-8') as f:
            conteudo = f.read().strip()
        if '|' in conteudo:
            return [conteudo]  # Uma linha com spintax
        else:
            return [l.strip() for l in conteudo.split('\n') if l.strip()]
    return ["Remitente"]

def carregar_links():
    if os.path.exists(ARQUIVO_LINKS):
        with open(ARQUIVO_LINKS, 'r', encoding='utf-8') as f:
            links = [l.strip() for l in f if l.strip() and not l.startswith('#')]
        return links if links else ["https://example.com"]
    return ["https://example.com"]

# ============================================================================
# ENVIAR EMAIL
# ============================================================================

def enviar_email(email_destino, html, assunto, remetente, usuario_num, links):
    try:
        usuario_email = f"user{usuario_num}@{DOMINIO}"

        # Gerar placeholders
        numero = gerar_numero()
        pros = gerar_pros()
        valor = gerar_valor(VALOR_BASE)
        data = datetime.now().strftime('%d/%m/%Y')
        hora = datetime.now().strftime('%H:%M')
        nome = extrair_nome(email_destino)
        dominio_dest = get_domain(email_destino)
        link = random.choice(links)

        # Processar assunto
        assunto_final = aplicar_spintax(assunto)
        assunto_final = replace_numero(assunto_final)
        assunto_final = replace_random(assunto_final)
        assunto_final = assunto_final.replace('{email}', email_destino)
        assunto_final = assunto_final.replace('{numero}', numero)
        assunto_final = assunto_final.replace('{valor}', valor)
        assunto_final = assunto_final.replace('{pros}', pros)
        assunto_final = assunto_final.replace('{link}', link)
        assunto_final = assunto_final.replace('{data}', data)
        assunto_final = assunto_final.replace('{hora}', hora)
        assunto_final = assunto_final.replace('{nombre}', nome)
        assunto_final = assunto_final.replace('{name}', nome)
        assunto_final = assunto_final.replace('{dominio}', dominio_dest)

        # Processar HTML
        html_final = aplicar_spintax(html)
        html_final = replace_numero(html_final)
        html_final = replace_random(html_final)
        html_final = html_final.replace('{email}', email_destino)
        html_final = html_final.replace('{numero}', numero)
        html_final = html_final.replace('{valor}', valor)
        html_final = html_final.replace('{pros}', pros)
        html_final = html_final.replace('{link}', link)
        html_final = html_final.replace('{data}', data)
        html_final = html_final.replace('{hora}', hora)
        html_final = html_final.replace('{nombre}', nome)
        html_final = html_final.replace('{name}', nome)
        html_final = html_final.replace('{dominio}', dominio_dest)

        # Criar mensagem
        msg = MIMEMultipart('alternative')
        msg['Subject'] = assunto_final
        msg['From'] = formataddr((remetente, usuario_email))  # Nome <email>
        msg['To'] = email_destino
        msg['Date'] = formatdate(localtime=True)
        msg['Message-ID'] = make_msgid(domain=get_domain(usuario_email))
        msg['X-Priority'] = '3'
        msg['X-Mailer'] = 'Python'

        msg.attach(MIMEText("test", 'plain', 'utf-8'))
        msg.attach(MIMEText(html_final, 'html', 'utf-8'))

        # Enviar
        smtp = smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=10)
        smtp.sendmail(usuario_email, [email_destino], msg.as_string())
        smtp.quit()

        return True, "OK"

    except Exception as e:
        return False, str(e)[:50]

# ============================================================================
# MAIN
# ============================================================================

def main():
    parser = argparse.ArgumentParser(description='Enviador CLI - Mass email sender')
    parser.add_argument('--batch', type=int, default=50, help='Batch size (default: 50)')
    parser.add_argument('--delay', type=int, default=100, help='Delay between emails in ms (default: 100)')
    parser.add_argument('--start', type=int, default=0, help='Start from email number (default: 0)')
    args = parser.parse_args()

    # Carregar dados
    print(f"{Colors.CYAN}📂 Carregando dados...{Colors.RESET}")
    htmls = carregar_htmls()
    emails = carregar_emails()
    assuntos = carregar_assuntos()
    remetentes = carregar_remetentes()
    links = carregar_links()

    if not htmls:
        print(f"{Colors.RED}❌ Nenhum HTML encontrado em {PASTA_HTML}{Colors.RESET}")
        return

    if not emails:
        print(f"{Colors.RED}❌ Nenhum email encontrado em {ARQUIVO_EMAILS}{Colors.RESET}")
        return

    print(f"{Colors.GREEN}✓ {len(htmls)} HTMLs carregados{Colors.RESET}")
    print(f"{Colors.GREEN}✓ {len(emails)} emails para enviar{Colors.RESET}")
    print(f"{Colors.GREEN}✓ {len(assuntos)} assuntos{Colors.RESET}")
    print(f"{Colors.GREEN}✓ {len(remetentes)} remetentes{Colors.RESET}")
    print()

    # Enviar
    inicio = time.time()
    enviados = 0
    falhas = 0
    html_idx = 0
    usuario_idx = 0

    total_emails = len(emails)

    for i, email in enumerate(emails[args.start:], start=args.start):
        email = email.strip()

        # Selecionar dados
        html = htmls[html_idx % len(htmls)]
        html_idx += 1

        assunto = random.choice(assuntos)
        remetente = aplicar_spintax(random.choice(remetentes))

        usuario_num = (usuario_idx % NUM_USUARIOS) + 1
        usuario_idx += 1

        # Enviar
        sucesso, msg = enviar_email(email, html, assunto, remetente, usuario_num, links)

        if sucesso:
            enviados += 1
            print(f"{Colors.GREEN}✓ [{i+1}/{total_emails}] {email[:30]} enviado{Colors.RESET}", flush=True)
        else:
            falhas += 1
            print(f"{Colors.RED}✗ [{i+1}/{total_emails}] {email[:30]} - {msg}{Colors.RESET}", flush=True)

        # Delay
        time.sleep(args.delay / 1000.0)

        # Mostrar taxa a cada 100
        if (i + 1) % 100 == 0:
            elapsed = time.time() - inicio
            taxa = (enviados / (elapsed / 3600)) if elapsed > 0 else 0
            print(f"{Colors.CYAN}   📊 Taxa: {taxa:.0f} emails/hora{Colors.RESET}")

    # Relatório final
    elapsed = time.time() - inicio
    taxa = (enviados / (elapsed / 3600)) if elapsed > 0 else 0

    print("\n" + "="*80)
    print(f"{Colors.GREEN}✓ Enviados: {enviados}{Colors.RESET}")
    print(f"{Colors.RED}✗ Falhas: {falhas}{Colors.RESET}")
    print(f"{Colors.YELLOW}⏱️  Tempo: {elapsed:.2f}s{Colors.RESET}")
    print(f"{Colors.CYAN}🚀 Taxa: {taxa:.0f} emails/hora{Colors.RESET}")
    print("="*80)

if __name__ == "__main__":
    main()
