import pandas as pd, numpy as np
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.metrics import roc_auc_score
pd.set_option('display.width',250)
d=pd.read_pickle('clean.pkl')
d=d[d.start=='small'].copy()
d['q']=d.quote.map({'0x'+'0'*40:0,'0x0bd7d308f8e1639fab988df18a8011f41eacad73':1,'0x5fc5360d0400a0fd4f2af552add042d716f1d168':2}).fillna(3)
d['hk']=np.where(d.hook=='0x'+'0'*40,0,np.where(d.hook_n==1,1,2))
d['fam_c']=d.fam.map({'organic':0,'bundle_eth':1,'campaign_weth':2})
d['hour']=((d.t0+7*3600)//3600%24)
days=sorted(d.day.unique())
def feats(T):
    X=pd.DataFrame(index=d.index)
    for c in ['mc','mcmax','nb','ns','bu','su']: X[c]=d['%s_%d'%(c,T)]
    TT=min(T,1800)
    for c in ['ub','top1b','top5b']: X[c]=d['%s_%d'%(c,TT)] if T>=30 else np.nan
    for L in [1e5,2.5e5,5e5,1e6]: X['s%g'%L]=(d['ts_%g'%L]<=T).astype(float)
    X['net']=X.bu-X.su; X['bs']=X.bu/(X.su+1)
    for c in ['first_buy_usd','buys_2s_usd','npools','q','hk','fee','hour','mc_first']: X[c]=d[c]
    return X
res=[]
for fam_inc in ['organic','all']:
  for T in [30,60,120,300,600,1800,3600]:
    X=feats(T)
    sub=d.fam.eq('organic') if fam_inc=='organic' else d.fam.ne('campaign_weth')
    for tgt,L in [('1M',1e6),('2M',2e6)]:
        y=(d['pa_%d'%T]>=L).astype(int)
        preds=[]; 
        for D in days[8:]:
            tr=sub&(d.day<D); te=sub&(d.day==D)
            if y[tr].sum()<5: continue
            m=HistGradientBoostingClassifier(max_iter=200,learning_rate=0.05,max_leaf_nodes=15,class_weight='balanced').fit(X[tr],y[tr])
            p=m.predict_proba(X[te])[:,1]; preds.append(pd.DataFrame({'p':p,'y':y[te].values,'day':D,'mc':X.mc[te].values}))
        P=pd.concat(preds)
        auc=roc_auc_score(P.y,P.p) if P.y.nunique()>1 else np.nan
        top=P.sort_values('p',ascending=False).groupby('day').head(3)
        top1=P.sort_values('p',ascending=False).groupby('day').head(1)
        res.append(dict(set=fam_inc,T=T,tgt=tgt,n=len(P),pos=int(P.y.sum()),auc=round(auc,3),top3_per_day_hit=round(top.y.mean()*100,1),top1_hit=round(top1.y.mean()*100,1),recall_top3=round(top.y.sum()/max(1,P.y.sum())*100,1),med_mc_top3=int(top.mc.median()) if len(top) else 0))
        print(res[-1],flush=True)
pd.DataFrame(res).to_csv('an4_model.csv',index=False)
