#!/usr/bin/env python3
import concurrent.futures,json,subprocess,sys,time
from pathlib import Path
PROJECT=Path('/data/video-pipeline/Youtube-Video-Maker/Project/03072026-003-Nguyen-Van-Troi')
GEN_SCRIPT=Path('/home/hermes/.hermes/skills/media/gen-img-gpt/scripts/gen_img_gpt.py')
LOG=PROJECT/'logs/step06_images_run.log'; MANIFEST=PROJECT/'logs/step06_images_manifest.json'; WORKERS=5
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 ref_for(scene):
    txt=(scene.get('narration') or scene.get('text') or '').lower(); refs=[]
    def add(n):
        p=PROJECT/f'characters/{n}_ref.png'
        if p.exists() and p.stat().st_size>1000: refs.append(str(p))
    if 'nguyễn văn trỗi' in txt or 'anh' in txt:
        if any(w in txt for w in ['chí hòa','pháp trường','xử bắn','bản án','tù','giam','thẩm vấn','nụ cười']): add('nguyen-van-troi-truoc-phap-truong')
        else: add('nguyen-van-troi-nguoi-tho-tre')
    if 'phan thị quyên' in txt or 'người vợ' in txt or 'vợ' in txt: add('phan-thi-quyen')
    if any(w in txt for w in ['biệt động','đồng đội','cách mạng','nhiệm vụ']): add('biet-dong-sai-gon-va-dong-doi')
    if any(w in txt for w in ['mỹ','cảnh sát','sài gòn','mcnamara','smolen','chính quyền']): add('canh-sat-sai-gon-va-co-van-my')
    if any(w in txt for w in ['dân','lao động','thợ','xóm','thành phố']): add('dan-lao-dong-sai-gon')
    return refs[:2]
def gen_one(scene):
    sid=scene['scene_id']; out=PROJECT/f'images/scenes/{sid}.png'
    if out.exists() and out.stat().st_size>1000: return {'scene_id':sid,'status':'exists','output':str(out)}
    prompt=scene.get('visual_prompt') or scene.get('visual_beat') or scene.get('text','')
    if scene.get('type')=='heading': prompt='Light Vietnamese old-calligraphy title-card on warm antique paper, subtle ink wash and small seal stamp accent, airy text with breathing room. Title text: '+scene.get('text','')+'. No modern typography, no heavy black title slam.'
    cmd=[sys.executable,str(GEN_SCRIPT)]
    for r in ref_for(scene): cmd+=['--input-ref',r]
    cmd+=['--prompt',prompt,'--output',str(out),'--size','auto','--quality','auto','--background','auto','--image-detail','high','--output-format','png','--n','1']
    try:
        p=subprocess.run(cmd,text=True,capture_output=True,timeout=900)
        if p.returncode!=0: return {'scene_id':sid,'status':'failed','error':(p.stderr or p.stdout)[-2000:]}
        return {'scene_id':sid,'status':'generated','output':str(out),'bytes':out.stat().st_size if out.exists() else 0}
    except Exception as e: return {'scene_id':sid,'status':'failed','error':repr(e)}
def gen_thumb(name,prompt):
    out=PROJECT/f'output/thumbnails/{name}'
    if out.exists() and out.stat().st_size>1000: return {'name':name,'status':'exists','output':str(out)}
    cmd=[sys.executable,str(GEN_SCRIPT),'--prompt',prompt,'--output',str(out),'--size','auto','--quality','auto','--background','auto','--image-detail','high','--output-format','png','--n','1']
    p=subprocess.run(cmd,text=True,capture_output=True,timeout=900)
    return {'name':name,'status':'generated' if p.returncode==0 else 'failed','output':str(out),'error':None if p.returncode==0 else (p.stderr or p.stdout)[-2000:]}
def main():
    LOG.write_text('',encoding='utf-8')
    plan=json.loads((PROJECT/'script/character_reference_plan.json').read_text(encoding='utf-8'))
    if not plan.get('validation',{}).get('required_refs_exist'): raise SystemExit('Step 06 blocked: required Step 05 refs missing')
    scenes=json.loads((PROJECT/'script/dense_scene_plan.json').read_text(encoding='utf-8'))['scenes']; results=[]
    with concurrent.futures.ThreadPoolExecutor(max_workers=WORKERS) as ex:
        futs={ex.submit(gen_one,s):s['scene_id'] for s in scenes}
        for fut in concurrent.futures.as_completed(futs):
            res=fut.result(); results.append(res); log(json.dumps(res,ensure_ascii=False)); MANIFEST.write_text(json.dumps({'project_id':PROJECT.name,'step':6,'scene_results':results},ensure_ascii=False,indent=2),encoding='utf-8')
    failed=[r for r in results if r['status']=='failed']
    if failed:
        MANIFEST.write_text(json.dumps({'project_id':PROJECT.name,'step':6,'status':'needs_retry','failed':failed,'scene_results':results},ensure_ascii=False,indent=2),encoding='utf-8'); raise SystemExit('step06_scene_failures')
    tp='cinematic Vietnamese historical biography poster for Việt Sử Kể Lại, NGUYỄN VĂN TRỖI, young electrician and resistance fighter, cầu Công Lý and pháp trường Chí Hòa memory, dramatic parchment texture, smoky Sài Gòn 1964, dark sepia bronze black palette, large respectful portrait with brave smile, readable metallic-gold Vietnamese brush lettering title: NGUYỄN VĂN TRỖI, black ink-splash grunge title panel, no modern objects, no watermark.'
    thumbs=[gen_thumb('thumb_16x9_final.png',tp+' 16:9 horizontal 1920x1080 composition.'),gen_thumb('thumb_9x16_final.png',tp+' TikTok-safe reduced portrait poster 1080x1280 composition, keep face and title central.')]
    MANIFEST.write_text(json.dumps({'project_id':PROJECT.name,'step':6,'status':'completed','total_scenes':len(scenes),'scene_results':results,'thumbnails':thumbs},ensure_ascii=False,indent=2),encoding='utf-8'); log('DONE '+json.dumps({'status':'completed','scenes':len(scenes),'thumbnails':thumbs},ensure_ascii=False))
if __name__=='__main__': main()
