from pathlib import Path
import pandas as pd,numpy as np,json
R=Path(__file__).resolve().parent;d=pd.read_parquet(R/'game_histories.parquet');rows=[]
for band,a in d.groupby('review_band'):
    valid=a[a.release_clock_valid]
    rows.append(dict(review_band=band,n=len(a),any_last12=int(a.last12_count.gt(0).sum()),atleast12_last12=int(a.last12_count.ge(12).sum()),active_9of12=int(a.last12_active_months.ge(9).sum()),median_last12=float(a.last12_count.median()),median_active_months=float(a.last12_active_months.median()),valid_release_n=len(valid),median_year1=float(valid.release_d365.median()),median_after90_year1_share=float(valid.year1_after90_share.median()),median_year2_year1=float(valid.year2_to_year1.median())))
pd.DataFrame(rows).to_csv(R/'current_review_band_details.csv',index=False)
rows=[]
for clock in ['release','firstreview']:
    for min_y1 in [1,10]:
        a=d[d.snapshot_reviews.ge(50)&d[f'{clock}_d365'].ge(min_y1)&d[f'{clock}_d90'].gt(0)].copy();ratio=a[f'{clock}_d365']/a[f'{clock}_d90'];share=(a[f'{clock}_d365']-a[f'{clock}_d90'])/a[f'{clock}_d365'];weights=a.weight.to_numpy()
        def wmed(x):
            x=np.asarray(x);order=np.argsort(x);xx=x[order];w=weights[order];return xx[np.searchsorted(np.cumsum(w),w.sum()/2)]
        rows.append(dict(clock=clock,min_year1=min_y1,n=len(a),weighted_year1_to90=wmed(ratio),weighted_after90_share=wmed(share),unweighted_year1_to90=float(ratio.median())))
pd.DataFrame(rows).to_csv(R/'clock_sensitivities.csv',index=False)
rows=[]
for threshold,ratio in [(15,3),(20,4),(50,6)]:
    for label,a in [('all_valid',d[d.release_clock_valid]),('50plus_valid',d[d.release_clock_valid&d.snapshot_reviews.ge(50)])]:
        rows.append(dict(threshold=threshold,ratio=ratio,population=label,n=len(a),games=int(a[f'bursts_{threshold}_{ratio}'].gt(0).sum()),episodes=int(a[f'bursts_{threshold}_{ratio}'].sum())))
pd.DataFrame(rows).to_csv(R/'burst_sensitivities.csv',index=False)
# Is later reception a little trickle or a substantial absolute addition?
v=d[d.release_clock_valid&d.snapshot_reviews.ge(50)].copy()
counts={f'at_least_{n}_after_year1':int(v.postyear1_count.ge(n).sum()) for n in [10,50,100,500]}
old=v[pd.to_datetime(v.date,utc=True)+pd.Timedelta(days=365)<=pd.Timestamp('2025-09-01',tz='UTC')]
counts.update(n=len(v),more_reviews_year2_than_year1=int(v.year2_to_year1.gt(1).sum()),mature_year2=int(v.year2_to_year1.notna().sum()),recent12_comparison_n=len(old),recent12_more_than_first365=int((old.last12_count>old.release_d365).sum()))
(R/'later_additions.json').write_text(json.dumps(counts,indent=2));print(counts)
extra=[]
for label,mask in [(p,d.period.eq(p)) for p in sorted(d.period.unique())]+[('exact_summary_matches',d.reconciliation_difference.eq(0))]:
    a=d[mask&d.snapshot_reviews.ge(50)&d.release_clock_valid]
    for metric in ['firstyear_share_of_current','year1_to90_ratio']:
        x=a[a[metric].notna()].sort_values(metric);v=x[metric].to_numpy();w=x.weight.to_numpy();med=float(v[np.searchsorted(np.cumsum(w),w.sum()/2)])
        extra.append(dict(group=label,metric=metric,n=len(x),weighted_median=med))
pd.DataFrame(extra).to_csv(R/'age_and_reconciliation_sensitivity.csv',index=False)
d[['appid','name','date','collected','release_clock_valid','release_d30','release_d90','release_d365','release_d730','last12_count','last12_active_months','bursts_20_4']].to_csv(R/'case_comparison.csv',index=False)
