"""Record the same real-app composer interactions against either checkout.
Usage: python composer-proof.py --browser agent-browser --session unique-name
  --origin http://127.0.0.1:PORT --pairing-file FILE --output DIRECTORY
  [--executable-path CHROME]
The project is seeded separately with `t3 project add PATH --title 'Composer demo'`.
No database fixtures, mocked UI, or direct editor mutations are used.
"""
import argparse, json, pathlib, subprocess, time
p=argparse.ArgumentParser()
for name in ('browser','session','origin','pairing-file','output'): p.add_argument('--'+name,required=True)
p.add_argument('--executable-path')
a=p.parse_args()
out=pathlib.Path(a.output)/time.strftime('%Y%m%d-%H%M%S'); out.mkdir(parents=True)
log=[]
def cmd(*args):
    r=subprocess.run([a.browser,'--session',a.session,*args],capture_output=True,text=True)
    if r.returncode: raise RuntimeError(' '.join(args[:2])+': '+r.stderr+r.stdout)
    return r.stdout.strip()
def evaluate(js):
    return json.loads(cmd('eval',js,'--json'))['data']['result']
def capture(label):
    # Hide the blinking caret only while checking stability and capturing a still.
    cmd('eval',"document.documentElement.style.setProperty('--proof-caret','transparent'); if(!document.getElementById('proof-caret')){const s=document.createElement('style');s.id='proof-caret';s.textContent='[contenteditable]{caret-color:var(--proof-caret,auto)!important}';document.head.append(s)}")
    one=out/(label+'-stability.png'); two=out/(label+'.png')
    for _ in range(12):
        cmd('screenshot',str(one)); time.sleep(.5); cmd('screenshot',str(two))
        if one.read_bytes()==two.read_bytes(): break
    else: raise RuntimeError('Screenshot never stabilized: '+label)
    cmd('eval',"document.documentElement.style.removeProperty('--proof-caret')")
def read_editor():
    return evaluate("(()=>{const e=document.querySelector('[data-testid=\"composer-editor\"]');return {text:e.innerText,html:e.innerHTML,rich:e.getAttribute('data-composer-rich-text')}})()")
def fill(text):
    cmd('click','[data-testid="composer-editor"]');cmd('press','Control+a');cmd('press','Backspace');cmd('keyboard','type',text)
    time.sleep(.15)
def press(key):
    if key == '*':cmd('keyboard','type',key)
    else:cmd('press',key)
    time.sleep(.15)
try:
    launch=['open',a.origin+pathlib.Path(a.pairing_file).read_text().strip()]
    if a.executable_path: launch=['--executable-path',a.executable_path,*launch]
    cmd(*launch)
    cmd('set','viewport','1280','800');cmd('set','media','dark')
    cmd('wait','[data-testid="composer-editor"]')
    cmd('open',a.origin+'/settings/chat');cmd('wait','[aria-label="Rich text composer"]')
    cmd('record','start',str(out/'composer-interactions.mp4'))
    cmd('click','[aria-label="Rich text composer"]')
    capture('plain-text-settings')
    cmd('find','role','button','click','--name','Close')
    cmd('wait','[data-testid="composer-editor"][data-composer-rich-text="false"]')
    for label,text,keys in [('plain-newline','1. item',['End','Shift+Enter']),('plain-delimiter','word',['Home','Shift+End','*']),('plain-tab','1. item',['End','Tab']),('plain-shift-tab','    1. item',['End','Shift+Tab']),('literal-decimal','1.0',['End','Shift+Enter'])]:
        fill(text)
        for k in keys: press(k)
        capture(label)
        log.append({'step':label,'start':text,'keys':keys,'result':read_editor()})
    fill('Send shortcut works');press('Enter')
    cmd('wait','--text','This turn is a replay.')
    capture('enter-send')
    log.append({'step':'enter-send','result':evaluate("document.querySelector('[role=\"region\"][aria-label=\"Conversation\"]')?.innerText")})
    # Re-enable rich text for the control.
    cmd('open',a.origin+'/settings/chat');cmd('wait','[aria-label="Rich text composer"]')
    cmd('click','[aria-label="Rich text composer"]');capture('rich-text-settings')
    cmd('find','role','button','click','--name','Close')
    cmd('wait','[data-testid="composer-editor"][data-composer-rich-text="true"]')
    for label,text,keys in [('rich-newline','1. item',['End','Shift+Enter']),('rich-delimiter','word',['Home','Shift+End','*']),('rich-tab','1. item',['End','Tab'])]:
        fill(text)
        for k in keys: press(k)
        capture(label);log.append({'step':label,'start':text,'keys':keys,'result':read_editor()})
finally:
    try:cmd('record','stop')
    except Exception:pass
    (out/'observations.json').write_text(json.dumps(log,indent=2))
    print(out)
