#!/usr/bin/env python3
"""Upload de emails da Hotmart pra Custom Audience existente no Meta Ads."""
import csv
import hashlib
import json
import sys
import time
import urllib.request
import urllib.error

CSV_PATH = "/opt/mia-bot/docs/1785262653959812.csv"
TOKEN_PATH = "/opt/mia/config/meta_token_renato.txt"
AUDIENCE_ID = "120249797003050103"
API_VERSION = "v21.0"
BATCH_SIZE = 10000
OUTBOX_DIR = "/opt/mia-bot/outbox"


def read_token() -> str:
    with open(TOKEN_PATH, "r", encoding="utf-8") as f:
        return f.read().strip()


def load_emails(path: str) -> list[str]:
    emails: list[str] = []
    with open(path, "r", encoding="utf-8-sig", newline="") as f:
        reader = csv.DictReader(f, delimiter=";")
        for row in reader:
            email = (row.get("Email") or "").strip().lower()
            if email:
                emails.append(email)
    return emails


def sha256_hex(value: str) -> str:
    return hashlib.sha256(value.encode("utf-8")).hexdigest()


def send_batch(token: str, audience_id: str, hashes: list[str],
               session_id: int, batch_seq: int, last_batch: bool,
               total: int) -> dict:
    url = f"https://graph.facebook.com/{API_VERSION}/{audience_id}/users"
    body = {
        "payload": {
            "schema": ["EMAIL_SHA256"],
            "data": [[h] for h in hashes],
        },
        "session": {
            "session_id": session_id,
            "batch_seq": batch_seq,
            "last_batch_flag": last_batch,
            "estimated_num_total": total,
        },
        "access_token": token,
    }
    data = json.dumps(body).encode("utf-8")
    req = urllib.request.Request(
        url,
        data=data,
        method="POST",
        headers={"Content-Type": "application/json"},
    )
    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        body_err = e.read().decode("utf-8", errors="replace")
        raise RuntimeError(f"HTTP {e.code}: {body_err}") from e


def send_outbox(text: str) -> None:
    fname = f"{OUTBOX_DIR}/{int(time.time() * 1e9)}.json"
    with open(fname, "w", encoding="utf-8") as f:
        json.dump({"text": text}, f, ensure_ascii=False)


def main() -> int:
    token = read_token()
    emails = load_emails(CSV_PATH)
    total = len(emails)
    print(f"[info] emails lidos: {total}", flush=True)

    hashes = [sha256_hex(e) for e in emails]
    session_id = int(time.time())

    batches = [hashes[i:i + BATCH_SIZE] for i in range(0, total, BATCH_SIZE)]
    total_received = 0
    total_invalid = 0
    responses = []

    for idx, batch in enumerate(batches, start=1):
        last = (idx == len(batches))
        print(f"[info] enviando batch {idx}/{len(batches)} "
              f"({len(batch)} hashes, last={last})", flush=True)
        resp = send_batch(
            token, AUDIENCE_ID, batch,
            session_id=session_id, batch_seq=idx,
            last_batch=last, total=total,
        )
        responses.append(resp)
        print(f"[info] resposta: {json.dumps(resp)}", flush=True)
        total_received += int(resp.get("num_received", 0))
        total_invalid += int(resp.get("num_invalid_entries", 0))

    resumo = (
        "Custom Audience Hotmart atualizada, chefe.\n\n"
        f"- Audience: 120249797003050103\n"
        f"- Emails do CSV: {total}\n"
        f"- Aceitos pelo Meta (num_received): {total_received}\n"
        f"- Invalidos (num_invalid_entries): {total_invalid}\n"
        f"- Session ID: {session_id}\n"
        f"- Batches enviados: {len(batches)}\n\n"
        f"Lookalike 120249797016970103 ja pode ser usado com dados reais - "
        f"o Meta leva de 30min a algumas horas pra reprocessar a semente."
    )
    send_outbox(resumo)
    print("[ok] outbox enviado", flush=True)
    return 0


if __name__ == "__main__":
    sys.exit(main())
