#!/usr/bin/env python3
from pathlib import Path
import json,hashlib,re,datetime
P='gacmai_20260717_184527';R=Path('/data/video-pipeline/GacMaiAudio/project')/P;A=R/'artifacts';story=A/'story_package_canonical.json';auth=A/'production_authorization.json';out=A/'tts_projection.json'
if out.exists():raise SystemExit('tts projection already exists')
for p in (story,auth):
 if not p.exists():raise SystemExit(f'missing {p.name}')
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
h=sha(story);a=json.loads(auth.read_text())
if a.get('status')!='passed' or a.get('story_sha256')!=h or a.get('tts_authorized') is not True or a.get('provider_spend_authorized') is not True:raise SystemExit('production authorization mismatch')
d=json.loads(story.read_text());segments=[]
for part in d.get('parts',[]):
 ps=part.get('paragraphs',[])
 if len(ps)!=12:raise SystemExit(f"P{part.get('part')} paragraph count")
 for i,x in enumerate(ps,1):
  t=x if isinstance(x,str) else x.get('text') or x.get('narration') or ''
  t=' '.join(t.split())
  if not t:raise SystemExit(f"empty P{part.get('part')}D{i}")
  segments.append({'id':f"P{part['part']:02d}D{i:02d}",'part':part['part'],'paragraph':i,'text':t})
if len(segments)!=144:raise SystemExit('segment count')
narration='\n\n'.join(x['text'] for x in segments)+'\n';payload={'status':'passed','project_id':P,'title':d['title'],'story_sha256':h,'voice':'Ngọc Huyền','segments':segments,'segment_count':144,'narration_sha256':hashlib.sha256(narration.encode()).hexdigest(),'created_at':datetime.datetime.now(datetime.timezone.utc).isoformat()};out.write_text(json.dumps(payload,ensure_ascii=False,indent=2)+'\n');(A/'narration.txt').write_text(narration);print(json.dumps({'status':'passed','projection_sha256':sha(out),'story_sha256':h,'segments':144,'narration_sha256':payload['narration_sha256']}))
