"""Persist actual authored critiques through the EXISTING review service, preserving every prior record."""
from pathlib import Path
import json,urllib.request,ssl,certifi,hashlib,datetime,time,concurrent.futures
root=Path(__file__).resolve().parents[1]
url='https://review.clientsflow.hu/__review-comments/comments?doc=komplex-rita-funnel-20260926-master'
context=ssl.create_default_context(cafile=certifi.where())
def request(payload=None):
 headers={'Accept':'application/json','User-Agent':'Mozilla/5.0'}
 if payload is not None:headers['Content-Type']='application/json'
 req=urllib.request.Request(url,data=json.dumps(payload,ensure_ascii=False).encode() if payload is not None else None,headers=headers,method='POST' if payload is not None else 'GET')
 with urllib.request.urlopen(req,context=context,timeout=30) as r:
  raw=r.read()
  if payload is not None:return {'http':r.status}
  data=json.loads(raw)
  assert isinstance(data,list),'Provider did not return a comments array'
  return data
before=request();(root/'private/comment-records-before-critique.json').write_text(json.dumps(before,ensure_ascii=False,indent=2))
by_id={r['id']:r for r in before};prepared=[];ts=int(time.time()*1000)
for i,r in enumerate(json.loads((root/'legacy/comments-ready.json').read_text())):
 ident='kl-legacy-critique-20261002-'+hashlib.sha256((r['cid']+'\n'+r['text']).encode()).hexdigest()[:18]
 record={'id':ident,'cid':r['cid'],'label':r['cid'].removeprefix('legacy-'),'text':r['text'],'author':r['author'],'ts':ts+i,'resolved':False}
 if ident in by_id:
  assert by_id[ident].get('text')==record['text'] and by_id[ident].get('cid')==record['cid'],'An existing record conflicts with this task-owned stable ID'
 else:prepared.append(record)
# One actual critique, not a test record, proves the existing write/read route before the remainder.
if prepared:
 first=prepared.pop(0);request(first);one=request();actual=next((r for r in one if r.get('id')==first['id']),None)
 assert actual and actual.get('text')==first['text'] and actual.get('cid')==first['cid'],'First actual critique could not be read back exactly'
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as ex:list(ex.map(request,prepared))
after=request();after_by_id={r['id']:r for r in after}
for ident,record in by_id.items():assert after_by_id.get(ident)==record,f'Prior record changed or disappeared: {ident}'
expected=json.loads((root/'legacy/comments-ready.json').read_text());verified=[]
for r in expected:
 ident='kl-legacy-critique-20261002-'+hashlib.sha256((r['cid']+'\n'+r['text']).encode()).hexdigest()[:18]
 actual=after_by_id.get(ident);assert actual and actual.get('text')==r['text'] and actual.get('cid')==r['cid']
 verified.append(ident)
receipt={'checked_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'route':url,'document_id':'komplex-rita-funnel-20260926-master','prior_records':len(before),'actual_critiques_readback':len(verified),'total_records':len(after),'all_prior_records_unchanged':True,'all_text_and_cid_exact':True,'task_owned_ids':verified,'backend_created_or_changed':False,'test_records_written':0,'note':'These are actual authored critiques. Browser widget reload/inline rewrite fixture acceptance is separate.'}
(root/'evidence/legacy-critique-provider-readback.json').write_text(json.dumps(receipt,ensure_ascii=False,indent=2));(root/'private/comment-records-after-critique.json').write_text(json.dumps(after,ensure_ascii=False,indent=2))
print(json.dumps({k:v for k,v in receipt.items() if k!='task_owned_ids'},ensure_ascii=False,indent=2))
