#!/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-002-Vo-Thi-Sau')
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(name):
        p=PROJECT/f'characters/{name}_ref.png'
        if p.exists() and p.stat().st_size>1000: refs.append(str(p))
    if 'võ thị sáu' in txt or 'sáu' in txt:
        if any(w in txt for w in ['côn đảo','nhà tù','pháp trường','xử bắn','bản án','tử tù','tra khảo']): add('vo-thi-sau-trong-tu-con-dao')
        else: add('vo-thi-sau-tuoi-thieu-nu')
    if any(w in txt for w in ['dân', 'chợ', 'xóm làng', 'đất đỏ']): add('dan-lang-dat-do')
    if any(w in txt for w in ['kháng chiến','đồng đội','giao liên','cách mạng','công an xung phong']): add('luc-luong-khang-chien-dat-do')
    if any(w in txt for w in ['pháp','thực dân','lính','tay sai','địch']): add('linh-phap-va-tay-sai')
    if any(w in txt for w in ['mẹ','gia đình']): add('me-va-gia-dinh-vo-thi-sau')
    return refs[:2]

def generate_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)}
    out.parent.mkdir(parents=True, exist_ok=True)
    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 red-earth 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 generate_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')
    ref_plan=json.loads((PROJECT/'script/character_reference_plan.json').read_text(encoding='utf-8'))
    if not ref_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(generate_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')
    thumb_prompt='cinematic Vietnamese historical biography poster for Việt Sử Kể Lại, VÕ THỊ SÁU, brave young woman from Đất Đỏ, red earth and Côn Đảo prison memory, dramatic parchment texture, smoky anti-colonial tension, dark sepia red-earth bronze black palette, large respectful portrait of Võ Thị Sáu, readable metallic-gold Vietnamese brush lettering title: VÕ THỊ SÁU, black ink-splash grunge title panel, no modern objects, no watermark.'
    thumbs=[generate_thumb('thumb_16x9_final.png', thumb_prompt+' 16:9 horizontal 1920x1080 composition.'), generate_thumb('thumb_9x16_final.png', thumb_prompt+' 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()
