# campaigns_2025_by_month.py
import os
from datetime import datetime, timezone, timedelta
from pathlib import Path
from dotenv import load_dotenv
from facebook_business.api import FacebookAdsApi
from facebook_business.adobjects.adaccount import AdAccount

load_dotenv()
ACCESS_TOKEN = os.getenv("FB_ACCESS_TOKEN")
ACCOUNT_ID   = os.getenv("AD_ACCOUNT_ID")
if not ACCESS_TOKEN or not ACCOUNT_ID:
    raise SystemExit("Missing FB_ACCESS_TOKEN or AD_ACCOUNT_ID in .env")
FacebookAdsApi.init(access_token=ACCESS_TOKEN)

SUMMARY_FILE = Path(__file__).with_name("summary2025.txt")

def nf(x):
    try:
        return float(x or 0)
    except Exception:
        return 0.0

def month_range_utc(y, m):
    start = datetime(y, m, 1, tzinfo=timezone.utc)
    if m == 12:
        nxt = datetime(y+1, 1, 1, tzinfo=timezone.utc)
    else:
        nxt = datetime(y, m+1, 1, tzinfo=timezone.utc)
    return start.strftime("%Y-%m-%d"), (nxt + timedelta(days=1)).strftime("%Y-%m-%d")

def campaigns_2025_by_month():
    year = 2025
    lead_keys = (
        "onsite_conversion.lead_grouped",
        "offsite_conversion.fb_pixel_lead",
        "lead",
        "leadgen.other",
    )
    results = {}
    month_totals = {}
    month_leads = {}

    last_month = datetime.now().month if datetime.now().year == year else 12
    for month in range(1, last_month + 1):
        since, until = month_range_utc(year, month)
        fields = ["campaign_id", "campaign_name", "spend", "actions", "cost_per_action_type"]
        params = {
            "level": "campaign",
            "time_range": {"since": since, "until": until},
            "action_report_time": "conversion",
            "action_attribution_windows": ["7d_click", "1d_view"],
            "limit": 5000,
        }

        rows = []
        month_total_spend_raw = 0.0
        month_total_leads_raw = 0.0

        cursor = AdAccount(ACCOUNT_ID).get_insights(fields=fields, params=params)
        for r in cursor:
            spend = nf(r.get("spend"))
            actions = {a.get("action_type"): a.get("value") for a in (r.get("actions") or [])}
            cpa     = {x.get("action_type"): x.get("value") for x in (r.get("cost_per_action_type") or [])}
            key     = next((k for k in lead_keys if k in actions), None)
            leads   = nf(actions.get(key)) if key else 0.0

            if spend == 0 and leads == 0:
                continue

            cpl = nf(cpa.get(key)) if key and cpa.get(key) is not None else (spend / leads if leads > 0 else 0.0)
            month_total_spend_raw += spend
            month_total_leads_raw += leads

            rows.append({
                "campaign_id":   r.get("campaign_id"),
                "campaign_name": r.get("campaign_name"),
                "leads": round(leads, 0),
                "spend": round(spend, 2),
                "cpl":   round(cpl, 2) if cpl else 0.0,
            })

        rows.sort(key=lambda x: x["spend"], reverse=True)
        ym = f"{year}-{month:02d}"
        results[ym] = rows
        month_totals[ym] = month_total_spend_raw
        month_leads[ym] = month_total_leads_raw

    return results, month_totals, month_leads


if __name__ == "__main__":
    data, month_totals, month_leads = campaigns_2025_by_month()

    lines = []
    grand_total_spend = 0.0
    grand_total_leads = 0.0

    for ym, rows in data.items():
        if not rows:
            continue
        monthly_total_spend = month_totals.get(ym, 0.0)
        monthly_total_leads = month_leads.get(ym, 0.0)
        grand_total_spend += monthly_total_spend
        grand_total_leads += monthly_total_leads

        lines.append(f"\n=== {ym} — Total Monthly Spent: {monthly_total_spend:.2f} | Total Leads: {monthly_total_leads:.0f} ===")
        for r in rows:
            lines.append(
                f"{r['campaign_name']} [{r['campaign_id']}] | Leads: {r['leads']:.0f} | "
                f"Spend: {r['spend']:.2f} | CPL: {r['cpl']:.2f}"
            )

    if grand_total_spend > 0:
        lines.append(f"\n=== 2025 TOTAL SPENT: {grand_total_spend:.2f} | TOTAL LEADS: {grand_total_leads:.0f} ===")

    Path(SUMMARY_FILE).write_text("\n".join(lines) + "\n", encoding="utf-8")
