#!/usr/bin/env python3
"""Crawl READ-ONLY conta Meta Borrello via UMA chamada com field expansion aninhado.
Minimiza calls pra nao bater rate limit (code 17)."""
import json, time, urllib.request, urllib.parse, urllib.error

API = "https://graph.facebook.com/v21.0"
ACT = "act_517468148842987"
with open("/opt/mia/config/meta_token_renato.txt") as f:
    TOKEN = f.read().strip()

def call(url):
    req = urllib.request.Request(url)
    with urllib.request.urlopen(req, timeout=180) as r:
        return json.loads(r.read().decode())

# Campos aninhados: campaign -> adsets{...ads{...}}
fields = (
    "id,name,objective,status,effective_status,daily_budget,lifetime_budget,buying_type,"
    "adsets.limit(100){id,name,status,effective_status,daily_budget,lifetime_budget,"
    "optimization_goal,billing_event,ads.limit(100){id,name,status,effective_status}}"
)
params = {
    "fields": fields,
    "filtering": json.dumps([{"field":"effective_status","operator":"IN",
        "value":["ACTIVE","PAUSED","CAMPAIGN_PAUSED","WITH_ISSUES","ADSET_PAUSED"]}]),
    "limit": 100,
    "access_token": TOKEN,
}
url = f"{API}/{ACT}/campaigns?" + urllib.parse.urlencode(params)

all_camps = []
attempt = 0
while url:
    ok = False
    for backoff in (0, 30, 60, 120, 180, 240):
        if backoff:
            time.sleep(backoff)
        try:
            d = call(url)
            ok = True
            break
        except urllib.error.HTTPError as e:
            body = e.read().decode()
            if '"code":17' in body or "request limit" in body.lower():
                print(f"[rate-limit, waiting... next backoff]", flush=True)
                continue
            else:
                print("FATAL:", body[:500]); raise
    if not ok:
        print("GIVEUP após retries"); break
    all_camps.extend(d.get("data", []))
    url = d.get("paging", {}).get("next")

with open("/opt/mia/workspace/temp/borrello_clean.json", "w") as f:
    json.dump(all_camps, f, ensure_ascii=False, indent=2)
print("OK campaigns:", len(all_camps))
