#!/usr/bin/env python3
"""Build full-viewport diffs, labelled sheets, real-time recording excerpts and review storyboards."""
from PIL import Image,ImageDraw,ImageFont
import numpy as np, pathlib,json,subprocess,shutil
R=pathlib.Path('/tmp/lead-26066-r1/evidence-capture-2')
RUNS={'SYM-B':'SYM-B-20261027T193724Z','SYM-A':'SYM-A-20261027T193724Z'}
font=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',22)
small=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',16)
for row,name in RUNS.items():
 r=R/name;im=Image.open(r/(row+'-1440x1000-dark.png')).convert('RGB');shutil.copyfile(r/(row+'-1440x1000-dark.png'),R/(row+'-1440x1000-dark.png'))
 sheet=Image.new('RGB',(1440,1070),'#171717');d=ImageDraw.Draw(sheet)
 sha='d0b81ceb6e' if row=='SYM-B' else 'ba74721bab';side='Before' if row=='SYM-B' else 'After'
 d.text((20,10),f'{row} | {side} {sha} | 1440 x 1000 CSS px | dark | DPR 1',font=font,fill='white')
 d.text((20,43),'Real web app / Chromium / Codex 0.163.0 / GPT-6-Astra / Medium / Auto workspace-write',font=small,fill='#bbb');sheet.paste(im,(0,70));sheet.save(R/(row+'-sheet.png'))
 src=next(r.glob('page@*.webm'));start=json.loads((r/'interaction-start.json').read_text())['seconds'];end=json.loads((r/'interaction-end.json').read_text())['seconds']
 # Preserve real-time motion and pauses; trim only auth/onboarding before the common interaction.
 subprocess.run(['ffmpeg','-hide_banner','-loglevel','error','-y','-ss',str(max(0,start-1)),'-i',str(src),'-t',str(end-start+2),'-c:v','libx264','-pix_fmt','yuv420p','-crf','20','-preset','fast','-movflags','+faststart',str(R/(row+'-1440x1000-dark.mp4'))],check=True)
 frames=r/'review-frames';frames.mkdir(exist_ok=True)
 subprocess.run(['ffmpeg','-hide_banner','-loglevel','error','-y','-i',str(R/(row+'-1440x1000-dark.mp4')),'-vf','fps=1,scale=480:-1',str(frames/'%03d.png')],check=True)
 ff=list(sorted(frames.glob('*.png')));story=Image.new('RGB',(1920,((len(ff)+3)//4)*360),'#222');dd=ImageDraw.Draw(story)
 for i,f in enumerate(ff):
  x=(i%4)*480;y=(i//4)*360;dd.text((x+8,y+3),f'{row} t={i}s',font=small,fill='white');story.paste(Image.open(f),(x,y+25))
 story.save(R/(row+'-storyboard.png'))
 shutil.copyfile(r/'manifest.json',R/(row+'-manifest.json'));shutil.copyfile(r/'timeline.json',R/(row+'-timeline.json'))
b=Image.open(R/'SYM-B-1440x1000-dark.png').convert('RGB');a=Image.open(R/'SYM-A-1440x1000-dark.png').convert('RGB');x=np.asarray(b).astype('int16');y=np.asarray(a).astype('int16');diff=np.abs(x-y).max(axis=2)
for label,t,color in [('diff0',0,(255,0,255)),('diff16',16,(255,160,0))]:
 out=(x*.35).astype('uint8');out[diff>t]=color;Image.fromarray(out).save(R/('SYM-'+label+'.png'))
stats={'metric':'maximum absolute RGB-channel difference, 8-bit','threshold0':{'pixels':int((diff>0).sum()),'percent':float((diff>0).mean()*100)},'threshold16':{'pixels':int((diff>16).sum()),'percent':float((diff>16).mean()*100)}}
stats['regions']={}
for name,(x0,y0,x1,y1) in {'footer':(0,950,256,1000),'sidebar':(0,0,256,1000),'outsideChatResult':(0,0,1440,1000)}.items():
 mask=np.zeros(diff.shape,dtype=bool);mask[y0:y1,x0:x1]=True
 if name=='outsideChatResult':mask[200:600,475:1225]=False
 stats['regions'][name]={'bounds':[x0,y0,x1,y1],'threshold0':int(((diff>0)&mask).sum()),'threshold16':int(((diff>16)&mask).sum())}
(R/'diff-stats.json').write_text(json.dumps(stats,indent=2))
ys,xs=np.where(diff>0)
(R/'delta-bounds.json').write_text(json.dumps({'bounds':[int(xs.min()),int(ys.min()),int(xs.max()+1),int(ys.max()+1)],'outsideChatPixels':[[int(xx),int(yy),int(diff[yy,xx])] for yy,xx in zip(ys,xs) if not(475<=xx<1225 and 200<=yy<600)]},indent=2))
pair=Image.new('RGB',(2880,2140),'#171717');d=ImageDraw.Draw(pair)
for i,(file,label) in enumerate([('SYM-B-1440x1000-dark.png','Before | SYM-B | d0b81ceb6e'),('SYM-A-1440x1000-dark.png','After | SYM-A | ba74721bab'),('SYM-diff0.png','Diff0 | ANY nonzero RGB difference -> magenta (1-level amplified)'),('SYM-diff16.png','DiffT | maximum RGB channel difference > 16/255 -> orange')]):
 xx=(i%2)*1440;yy=(i//2)*1070;d.text((xx+20,yy+20),label,font=font,fill='white');pair.paste(Image.open(R/file),(xx,yy+70))
pair.save(R/'SYM-comparison-sheet.png')
