#!/usr/bin/env python3
import json, re, subprocess, sys, time
from pathlib import Path
import importlib.util
PROJECT=Path('/data/video-pipeline/Youtube-Video-Maker/Project/29062026-001-Nha-Mac')
RUN=PROJECT/'scripts_run_step_06_images.py'
LOG=PROJECT/'logs/step06_missing_retry_run.log'
MANIFEST=PROJECT/'logs/step06_missing_retry_manifest.json'

def load_runner():
    spec=importlib.util.spec_from_file_location('step06', RUN)
    mod=importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod

def log(msg):
    line=time.strftime('%Y-%m-%d %H:%M:%S ')+msg
    print(line, flush=True)
    LOG.parent.mkdir(parents=True, exist_ok=True)
    with LOG.open('a', encoding='utf-8') as f: f.write(line+'\n')

def reset_wait(err):
    m=re.search(r'reset after\s+(?:(\d+)m\s*)?(\d+)s', err or '', re.I)
    if not m: return 75
    mins=int(m.group(1) or 0); secs=int(m.group(2) or 0)
    return max(45, mins*60+secs+35)

def main():
    LOG.write_text('', encoding='utf-8')
    mod=load_runner(); refs=mod.load_refs()
    scenes=json.loads(mod.SCENES.read_text(encoding='utf-8'))['scenes']
    results=[]
    for scene in scenes:
        out=mod.OUT_SCENES/f"{scene['scene_id']}.png"
        if out.exists() and out.stat().st_size>1000:
            continue
        attempts=0
        while attempts<5:
            attempts+=1
            log(f"RETRY {scene['scene_id']} attempt={attempts}")
            r=mod.run_one(scene, refs)
            results.append(r)
            if r['status'] in ('ok','skipped_exists'):
                log(f"OK {scene['scene_id']} bytes={r.get('bytes')}")
                break
            err=r.get('error','')
            wait=reset_wait(err)
            log(f"FAILED {scene['scene_id']} wait={wait}s error={(err or '')[:500].replace(chr(10),' | ')}")
            time.sleep(wait)
        if not (out.exists() and out.stat().st_size>1000):
            MANIFEST.write_text(json.dumps({'status':'blocked','failed_scene':scene['scene_id'],'results':results},ensure_ascii=False,indent=2),encoding='utf-8')
            raise SystemExit('blocked '+scene['scene_id'])
    # All scenes exist, generate thumbnails if needed via original runner helpers.
    thumbs=[]
    mod.OUT_THUMBS.mkdir(parents=True, exist_ok=True)
    for kind,name in [('16x9','thumb_16x9_final.png'),('9x16','thumb_9x16_final.png')]:
        out=mod.OUT_THUMBS/name
        attempts=0
        while attempts<5:
            attempts+=1
            log(f"THUMB {kind} attempt={attempts}")
            r=mod.gen_thumb(kind,out,refs)
            thumbs.append(r)
            if r['status'] in ('ok','skipped_exists'):
                log(f"THUMB_OK {kind} bytes={r.get('bytes')}")
                break
            wait=reset_wait(r.get('error',''))
            log(f"THUMB_FAILED {kind} wait={wait}s error={(r.get('error','') or '')[:500].replace(chr(10),' | ')}")
            time.sleep(wait)
        if not (out.exists() and out.stat().st_size>1000):
            MANIFEST.write_text(json.dumps({'status':'blocked','results':results,'thumbs':thumbs},ensure_ascii=False,indent=2),encoding='utf-8')
            raise SystemExit('thumb blocked '+kind)
    # Rewrite official manifest/checklist as completed.
    scene_results=[]
    for scene in scenes:
        out=mod.OUT_SCENES/f"{scene['scene_id']}.png"
        scene_results.append({'scene_id':scene['scene_id'],'status':'skipped_exists','output':str(out),'bytes':out.stat().st_size})
    thumb_results=[]
    for kind,name in [('16x9','thumb_16x9_final.png'),('9x16','thumb_9x16_final.png')]:
        out=mod.OUT_THUMBS/name
        thumb_results.append({'kind':kind,'status':'skipped_exists','output':str(out),'bytes':out.stat().st_size})
    mod.MANIFEST.write_text(json.dumps({'project_id':PROJECT.name,'step':6,'status':'completed','workers':'polite-missing-retry','total_scenes':len(scenes),'scene_results':scene_results,'thumbnail_results':thumb_results},ensure_ascii=False,indent=2),encoding='utf-8')
    check=json.loads((PROJECT/'checklist_19_steps.json').read_text(encoding='utf-8'))
    check['steps'][4]['status']='completed'; check['steps'][5]['status']='completed'; check['current_step']=6
    (PROJECT/'checklist_19_steps.json').write_text(json.dumps(check,ensure_ascii=False,indent=2),encoding='utf-8')
    (PROJECT/'checklist_19_steps.md').write_text('# Checklist 19 Steps\n\n'+'\n'.join(f"- [{'x' if s['status']=='completed' else ' '}] Step {s['step']:02d}: {s['status']}" for s in check['steps'])+'\n',encoding='utf-8')
    MANIFEST.write_text(json.dumps({'status':'completed','scene_retry_results':results,'thumbnail_results':thumbs},ensure_ascii=False,indent=2),encoding='utf-8')
    log('DONE completed')
if __name__=='__main__': main()
