import asyncio, json, time
import websockets

WS="wss://ourworldoftext.com/ws/"
gx, gy = -32, 8   # tile (-2,1), row 0
W=52

def cell_of(x,y):
    tx,ty=x//16,y//8
    return tx,ty,x-tx*16,y-ty*8

async def fetch_row(ws):
    # fetch tiles covering x in [gx, gx+W-1] at y=gy
    txs=sorted({cell_of(x,gy)[0] for x in range(gx,gx+W)})
    await ws.send(json.dumps({"kind":"fetch","fetchRectangles":[{"minX":min(txs),"minY":1,"maxX":max(txs),"maxY":1}]}))
    tiles={}
    t0=time.monotonic()
    while time.monotonic()-t0<6:
        d=json.loads(await asyncio.wait_for(ws.recv(),timeout=5))
        if d.get("kind")=="fetch":
            for k,v in d["tiles"].items():
                ty,tx=map(int,k.split(",")); tiles[(tx,ty)]=v
            if all((tx,1) in tiles for tx in txs): break
    row=[]
    for x in range(gx,gx+W):
        tx,ty,cx,cy=cell_of(x,gy)
        v=tiles.get((tx,1))
        if not v: row.append(" ")
        else:
            i=cy*16+cx; c=v.get("content"," "*128)
            row.append(c[i] if i<len(c) else " ")
    return "".join(row), tiles

def orig_cell(tiles,x):
    tx,ty,cx,cy=cell_of(x,gy); v=tiles.get((tx,1))
    if not v: return " ",0,-1
    i=cy*16+cx; c=v.get("content"," "*128); p=v.get("properties",{}) or {}
    ch=c[i] if i<len(c) else " "
    col=(p.get("color") or [0]*128); col=col[i] if i<len(col) and col[i] is not None else 0
    bg=(p.get("bgcolor") or [-1]*128); bg=bg[i] if i<len(bg) and bg[i] is not None else -1
    return ch,col,bg

async def write_cells(ws,cells,seq):
    edits=[]; ts=int(time.time()*1000)
    for x,ch,col,bg in cells:
        tx,ty,cx,cy=cell_of(x,gy); edits.append([ty,tx,cy,cx,ts,ch,seq[0],col,bg]); seq[0]+=1
    await ws.send(json.dumps({"kind":"write","edits":edits}))

async def main():
    async with websockets.connect(WS,origin="https://ourworldoftext.com",
            additional_headers={"User-Agent":"Mozilla/5.0 Chrome/120"},max_size=None,open_timeout=20) as ws:
        seq=[1]
        original, tiles = await fetch_row(ws)
        print("ORIGINAL row:", repr(original))
        # write progress line
        line=("ARCHIVING (128,64) [######----] 61%").ljust(W)[:W]
        await write_cells(ws,[(gx+i,ch,0xFF0000,-1) for i,ch in enumerate(line)],seq)
        await asyncio.sleep(1.5)
        after,_=await fetch_row(ws)
        print("AFTER WRITE :", repr(after))
        wrote_ok = after.strip().startswith("ARCHIVING")
        # restore originals
        restore=[(gx+i,)+orig_cell(tiles,gx+i) for i in range(W)]
        restore=[(x, ch if ch else " ", col, bg) for (x,ch,col,bg) in restore]
        await write_cells(ws,restore,seq)
        await asyncio.sleep(1.5)
        final,_=await fetch_row(ws)
        print("AFTER RESTORE:", repr(final))
        print("WROTE_OK =", wrote_ok, " RESTORED_OK =", final==original)
asyncio.run(main())
