#!/usr/bin/env python3
import concurrent.futures, json, os, subprocess, sys, time
from pathlib import Path

PROJECT = Path('/data/video-pipeline/Youtube-Video-Maker/Project/28052026-002-Tran-Quang-Dieu-Bui-Thi-Xuan')
GEN_SCRIPT = Path('/home/hermes/.hermes/skills/media/gen-img-gpt/scripts/gen_img_gpt.py')
SCENES = PROJECT / 'script/scenes.json'
PLAN = PROJECT / 'script/character_reference_plan.json'
OUT_SCENES = PROJECT / 'images/scenes'
OUT_THUMBS = PROJECT / 'output/thumbnails'
LOG = PROJECT / 'logs/step06_images_run.log'
MANIFEST = PROJECT / 'logs/step06_images_manifest.json'
WORKERS = int(os.environ.get('STEP06_WORKERS', '7'))

STYLE_SCENE = "16:9 horizontal historical storytelling image, centered irregular ink-wash narrative window on warm antique cream paper, painted content occupies only about 65-70 percent of page with 30-35 percent clean antique paper negative space, handcrafted Vietnamese co phong feeling, muted brown black charcoal watercolor wash, not modern, not full-frame glossy digital poster, not fantasy splash art, not 3D game key art, no text, no watermark."
STYLE_HEADING = "16:9 horizontal light Vietnamese old-calligraphy title-card on warm antique paper, subtle ink wash and small red seal stamp accent, airy text with breathing room, not heavy black title slam, not clean modern typography."
NEG = "Avoid modern objects, wrong culture, Chinese opera costume, European armor, fantasy armor, samurai, gun unless historically contextualized, character sheet layout, model sheet, multiple views, floating costume parts, text labels, watermark, logo, glossy poster, edge-to-edge full-frame painting."

REFS = {
    'tran_quang_dieu': PROJECT/'images/refs/tran_quang_dieu_ref.png',
    'bui_thi_xuan': PROJECT/'images/refs/bui_thi_xuan_ref.png',
    'quang_trung': PROJECT/'images/refs/quang_trung_ref.png',
    'nguyen_anh': PROJECT/'images/refs/nguyen_anh_ref.png',
}

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 scene_refs(text):
    t = text.lower()
    refs = []
    if 'trần quang diệu' in t: refs.append(REFS['tran_quang_dieu'])
    if 'bùi thị xuân' in t: refs.append(REFS['bui_thi_xuan'])
    if 'quang trung' in t or 'nguyễn huệ' in t: refs.append(REFS['quang_trung'])
    if 'nguyễn ánh' in t or 'gia long' in t: refs.append(REFS['nguyen_anh'])
    return [p for p in refs if p.exists()]

def prompt_for(scene):
    if scene.get('type') == 'heading':
        return f"{STYLE_HEADING}\nVietnamese title card text to depict accurately if possible: {scene['narration']}\nNo character portraits unless subtle silhouettes are needed. {NEG}"
    refs = scene_refs(scene.get('narration','') + ' ' + scene.get('summary',''))
    ref_note = ''
    if refs:
        ref_note = 'Use attached character reference image(s) only to keep identity, age, face, costume language, and temperament consistent. Do not reproduce a reference sheet. Create one cinematic story scene with environment and action. '
    return f"{STYLE_SCENE}\nHistorical context: late 18th century Vietnam, Tây Sơn era, Bình Định martial land, war and political upheaval.\nNarration beat: {scene['narration']}\nVisual direction: {scene.get('visual_beat') or scene.get('visual_prompt')}\n{ref_note}One cinematic narrative scene, historically grounded Vietnamese clothing, armor, weapons, architecture, terrain, and atmosphere.\nNegative exclusions: {NEG}"

def run_one(scene):
    out = OUT_SCENES / f"{scene['scene_id']}.png"
    if out.exists() and out.stat().st_size > 1000:
        return {'scene_id': scene['scene_id'], 'status': 'skipped_exists', 'output': str(out), 'bytes': out.stat().st_size}
    cmd = [sys.executable, str(GEN_SCRIPT), '--prompt', prompt_for(scene), '--output', str(out), '--size', 'auto', '--quality', 'auto', '--background', 'auto', '--image-detail', 'high', '--output-format', 'png', '--n', '1']
    for ref in scene_refs(scene.get('narration','') + ' ' + scene.get('summary',''))[:2]:
        cmd += ['--input-ref', str(ref)]
    p = subprocess.run(cmd, text=True, capture_output=True, timeout=1200)
    if p.returncode != 0:
        return {'scene_id': scene['scene_id'], 'status': 'failed', 'output': str(out), 'error': (p.stderr or p.stdout)[-2000:]}
    return {'scene_id': scene['scene_id'], 'status': 'ok', 'output': str(out), 'bytes': out.stat().st_size if out.exists() else 0}

def thumb_prompt(kind):
    aspect = '16:9 YouTube thumbnail, 1920x1080' if kind == '16x9' else '9:16 vertical short thumbnail/poster, 1080x1920'
    return f"{aspect}. Cinematic Vietnamese historical biography poster for the story title 'HAI NGỌN GIÁO GIỮA BÃO TÂY SƠN'. Large dramatic portraits of Trần Quang Diệu and Bùi Thị Xuân, husband and wife Tây Sơn generals, with smoky battlefield, war elephant silhouette, Tây Sơn banners, parchment manuscript texture, dark sepia bronze black palette, large readable metallic-gold Vietnamese brush lettering over irregular black ink-splash title panel. Historically grounded late 18th century Vietnam, not modern, not fantasy, no watermark."

def gen_thumb(kind, out):
    if out.exists() and out.stat().st_size > 1000:
        return {'kind': kind, 'status': 'skipped_exists', 'output': str(out), 'bytes': out.stat().st_size}
    cmd = [sys.executable, str(GEN_SCRIPT), '--prompt', thumb_prompt(kind), '--output', str(out), '--size', 'auto', '--quality', 'auto', '--background', 'auto', '--image-detail', 'high', '--output-format', 'png', '--n', '1', '--input-ref', str(REFS['tran_quang_dieu']), '--input-ref', str(REFS['bui_thi_xuan'])]
    p = subprocess.run(cmd, text=True, capture_output=True, timeout=1200)
    if p.returncode != 0:
        return {'kind': kind, 'status': 'failed', 'output': str(out), 'error': (p.stderr or p.stdout)[-2000:]}
    return {'kind': kind, 'status': 'ok', 'output': str(out), 'bytes': out.stat().st_size if out.exists() else 0}

def main():
    OUT_SCENES.mkdir(parents=True, exist_ok=True); OUT_THUMBS.mkdir(parents=True, exist_ok=True); LOG.parent.mkdir(parents=True, exist_ok=True)
    doc = json.loads(SCENES.read_text(encoding='utf-8'))
    scenes = doc['scenes']
    results=[]
    log(f'START step6 scenes={len(scenes)} workers={WORKERS}')
    with concurrent.futures.ThreadPoolExecutor(max_workers=WORKERS) as ex:
        futs = {ex.submit(run_one, s): s for s in scenes}
        for fut in concurrent.futures.as_completed(futs):
            r = fut.result(); results.append(r)
            log(f"{r['status']} {r.get('scene_id')} bytes={r.get('bytes')}" if 'scene_id' in r else str(r))
            if r['status'] == 'failed':
                log('ERROR '+r['scene_id']+' '+r.get('error','')[:500])
    thumb_results=[]
    if not any(r['status']=='failed' for r in results):
        log('START thumbnails')
        thumb_results.append(gen_thumb('16x9', OUT_THUMBS/'thumb_16x9_final.png'))
        log(str(thumb_results[-1]))
        thumb_results.append(gen_thumb('9x16', OUT_THUMBS/'thumb_9x16_final.png'))
        log(str(thumb_results[-1]))
    status = 'completed' if all(r['status'] in ('ok','skipped_exists') for r in results) and all(r['status'] in ('ok','skipped_exists') for r in thumb_results) and len(thumb_results)==2 else 'needs_retry'
    manifest={'project_id':PROJECT.name,'step':6,'status':status,'workers':WORKERS,'total_scenes':len(scenes),'scene_results':results,'thumbnail_results':thumb_results,'outputs':{'scenes_dir':str(OUT_SCENES),'thumbnails_dir':str(OUT_THUMBS)}}
    MANIFEST.write_text(json.dumps(manifest,ensure_ascii=False,indent=2),encoding='utf-8')
    log('DONE '+json.dumps({'status':status,'scenes_done':sum(1 for r in results if r['status'] in ('ok','skipped_exists')),'scenes_total':len(scenes),'thumbs':len(thumb_results)},ensure_ascii=False))
    if status != 'completed':
        raise SystemExit('needs_retry')

if __name__ == '__main__':
    main()
