"""Replicate the Mag 7 six-quarter FCF pull using edgartools, for head-to-head
comparison against the raw data.sec.gov XBRL company-concept API."""
from edgar import *
set_identity("Your Name your@email.com")
import pandas as pd, json, datetime as dt

TICKERS = {"Apple":"AAPL","Microsoft":"MSFT","Alphabet":"GOOGL","Amazon":"AMZN",
           "Nvidia":"NVDA","Meta":"META","Tesla":"TSLA"}
OCF = "NetCashProvidedByUsedInOperatingActivities"
CAPEX_CANDIDATES = ["PaymentsToAcquirePropertyPlantAndEquipment","PaymentsToAcquireProductiveAssets"]

def get_facts(facts, concept):
    df = facts.query().by_concept(concept).to_dataframe()
    if df is None or len(df)==0: return pd.DataFrame()
    df = df[df.period_type=="duration"].copy()
    if len(df)==0: return df
    df["period_start"]=pd.to_datetime(df.period_start); df["period_end"]=pd.to_datetime(df.period_end)
    df["filing_date"]=pd.to_datetime(df.filing_date)
    df["dur"]=(df.period_end-df.period_start).dt.days
    # dedupe: LATEST-filed accession wins. A restated figure is the company's current
    # statement of the fact; keeping a superseded value leaves part of the series on an
    # old basis. See restatement_audit.py for the one cell where this matters.
    df = df.sort_values("filing_date").drop_duplicates(subset=["period_start","period_end"], keep="last")
    return df.sort_values("period_end")

def discrete_quarters(df):
    """Return {period_end_date: discrete_quarter_value}. Prefers natively-tagged
    ~90-day facts; otherwise de-cumulates within each YTD chain (same period_start)."""
    out={}
    if len(df)==0: return out
    native = df[df.dur.between(80,100)]
    for _,r in native.iterrows(): out[r.period_end.date()] = r.numeric_value
    for start, grp in df.groupby("period_start"):
        grp=grp.sort_values("period_end"); prev=0.0
        for _,r in grp.iterrows():
            d = r.numeric_value - prev; prev = r.numeric_value
            if r.period_end.date() not in out and 80 <= r.dur <= 400:
                out[r.period_end.date()] = d
    return out

def nearest_cq(d):
    """Map a fiscal period-end date to the nearest calendar quarter label."""
    y,m = d.year, d.month
    anchors = [(y-1,12),(y,3),(y,6),(y,9),(y,12),(y+1,3)]
    best=None
    for ay,am in anchors:
        last = dt.date(ay+(am==12), (am%12)+1, 1) - dt.timedelta(days=1)
        dist = abs((d-last).days)
        if best is None or dist<best[0]: best=(dist,ay,am)
    _,ay,am = best
    return f"CY{ay}Q{(am-1)//3+1}"

Q=["CY2024Q4","CY2025Q1","CY2025Q2","CY2025Q3","CY2025Q4","CY2026Q1"]
result={}; meta={}
for name,tk in TICKERS.items():
    facts = Company(tk).facts
    o = get_facts(facts, OCF)
    cap=pd.DataFrame(); used=None
    for cand in CAPEX_CANDIDATES:
        c = get_facts(facts, cand)
        if len(c) and c.period_end.max() >= pd.Timestamp("2025-01-01"):
            cap, used = c, cand; break
    oq, cq = discrete_quarters(o), discrete_quarters(cap)
    om = {nearest_cq(k):v for k,v in oq.items()}
    cm = {nearest_cq(k):v for k,v in cq.items()}
    result[name]={q:{"ocf":om.get(q), "capex":cm.get(q)} for q in Q}
    meta[name]={"ticker":tk,"capex_tag":used,"ocf_facts":len(o),"capex_facts":len(cap)}
    print(f"{name:<10} capex_tag={used:<42} ocf_facts={len(o):>3} capex_facts={len(cap):>3}")

json.dump({"quarters":Q,"result":result,"meta":meta}, open("data/edgartools_fcf.json","w"), indent=1, default=str)
print("\nwrote data/edgartools_fcf.json")
