import json, os, subprocess, time, datetime, traceback
P='/data/video-pipeline/Youtube-Video-Maker/Project/24052026-001-Ly-Thuong-Kiet'
SCRIPT='/home/onepiece/.openclaw/workspace/skills/vietneu-tts/scripts/vietneu_tts.py'
scenes=json.load(open(P+'/script/scenes.json'))
textdir=P+'/script/tts_text'; outdir=P+'/audio/scenes'; logdir=P+'/logs'
os.makedirs(textdir,exist_ok=True); os.makedirs(outdir,exist_ok=True)
progress=logdir+'/tts_progress.json'
def now(): return datetime.datetime.utcnow().isoformat()+'Z'
def count_done(): return len([f for f in os.listdir(outdir) if f.startswith('scene_') and f.endswith('.wav') and os.path.getsize(os.path.join(outdir,f))>1000])
def save(extra=None):
 data={'updated_utc':now(),'project_id':'24052026-001-Ly-Thuong-Kiet','total':len(scenes),'done':count_done(),'remaining':len(scenes)-count_done(),'status':'running'}
 if extra: data.update(extra)
 open(progress,'w').write(json.dumps(data,ensure_ascii=False,indent=2))
failed=[]; save({'note':'tts started'})
for s in scenes:
 sid=s['scene_id']; out=f'{outdir}/scene_{sid:03d}.wav'; txt=f'{textdir}/scene_{sid:03d}.txt'
 if os.path.exists(out) and os.path.getsize(out)>1000:
  save({'last_result':{'scene_id':sid,'status':'exists'},'failed_count':len(failed)}); continue
 open(txt,'w').write(s['narration'])
 last=''
 ok=False
 for attempt in range(1,4):
  try:
   r=subprocess.run(['python3',SCRIPT,'--project-id','24052026-001-Ly-Thuong-Kiet','--text-file',txt,'--output-name',f'scenes/scene_{sid:03d}.wav','--timeout','240'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,timeout=360)
   last=(r.stdout+'\n'+r.stderr)[-2000:]
   if r.returncode==0 and os.path.exists(out) and os.path.getsize(out)>1000:
    ok=True; open(f'{logdir}/tts_scene_{sid:03d}.log','w').write(last); break
  except Exception:
   last=traceback.format_exc()[-2000:]
  time.sleep(10*attempt)
 if not ok:
  failed.append({'scene_id':sid,'error':last[-500:]})
  open(f'{logdir}/tts_scene_{sid:03d}.ERROR.log','w').write(last)
 save({'last_result':{'scene_id':sid,'status':'ok' if ok else 'failed'},'failed_count':len(failed)})
save({'status':'completed' if not failed else 'completed_with_failures','failed_count':len(failed),'failed':failed[:20]})
