from PIL import Image
import numpy as np, json
im=np.array(Image.open('ai-payment-volume.png').convert('RGB')).astype(float)
H,W,_=im.shape
R,G,B=im[...,0],im[...,1],im[...,2]
# gridlines: rows where column 60 is darker than background
col=im[:,60].sum(axis=1)
bg=243+244+246
d=np.clip(bg-col,0,None)
rows=np.where(d>15)[0]
groups=[];s=rows[0];p=rows[0]
for r in rows[1:]:
    if r-p>3: groups.append((s,p)); s=r
    p=r
groups.append((s,p))
grid=[]
for a,b in groups:
    ys=np.arange(a-1,b+2); w=d[a-1:b+2]
    grid.append(float((ys*w).sum()/w.sum()))
print('gridlines',[round(g,2) for g in grid])
grid=[g for g in grid if g<1050]
base=grid[-1]; step=np.diff(grid).mean()
print('baseline',round(base,2),'mean step',round(step,3),'steps',[round(x,2) for x in np.diff(grid)])
purple=np.clip((B-R-20)/155,0,1)
orange=np.clip((R-B-30)/205,0,1)*(G<215)
X0=117.5; DX=30.25
def center(wimg,x,ylo,yhi):
    w=wimg[ylo:yhi,x]
    if w.sum()<2: return None
    ys=np.arange(ylo,yhi)
    return float((ys*w).sum()/w.sum()), float(w.sum())
def series(wimg,ylo,yhi,n):
    # per-segment line fits
    est={k:[] for k in range(n)}
    for k in range(n-1):
        xa=X0+DX*k; xb=X0+DX*(k+1)
        pts=[]
        for x in range(int(np.ceil(xa+6)),int(np.floor(xb-6))+1):
            c=center(wimg,x,ylo,yhi)
            if c: pts.append((x,c[0]))
        if len(pts)<5: continue
        xs=np.array([p[0] for p in pts]); ys=np.array([p[1] for p in pts])
        m,b=np.polyfit(xs,ys,1)
        res=ys-(m*xs+b)
        est[k].append(m*xa+b); est[k+1].append(m*xb+b)
    return {k:(float(np.mean(v)),float(np.ptp(v)) if len(v)>1 else 0.0) for k,v in est.items() if v}
# find number of points: US line rightmost purple col below y=180 region excluding label (label x>1350)
pcols=[x for x in range(0,1345) if purple[40:1005,x].sum()>2]
ocols=[x for x in range(0,1345) if orange[900:1008,x].sum()>2]
print('US cols',min(pcols),max(pcols),'EU cols',min(ocols),max(ocols))
n=int(round((max(pcols)-4-X0)/DX))+1
print('n points',n,'last x',X0+DX*(n-1))
us=series(purple[:, :],40,1005,n)
eu=series(orange,900,1008,n)
import datetime
out=[]
for k in range(n):
    yr=2023+k//12; mo=k%12+1
    u=us.get(k); e=eu.get(k)
    uh=base-u[0] if u else None; eh=base-e[0] if e else None
    out.append(dict(month=f"{yr}-{mo:02d}",us_px=round(uh,2) if uh else None,eu_px=round(eh,2) if eh else None,us_spread=round(u[1],2) if u else None,eu_spread=round(e[1],2) if e else None))
for o in out: print(o)
json.dump(dict(baseline=base,grid=grid,step=step,x0=X0,dx=DX,points=out),open('digitized.json','w'),indent=1)
