#!/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/29052026-001-Nguyen-Phi-Y-Lan')
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 = {
    'y_lan': PROJECT/'characters/y_lan_ref.png',
    'ly_thanh_tong': PROJECT/'characters/ly_thanh_tong_ref.png',
    'ly_nhan_tong': PROJECT/'characters/ly_nhan_tong_ref.png',
    'ly_thuong_kiet': PROJECT/'characters/ly_thuong_kiet_ref.png',
    'thuong_duong': PROJECT/'characters/thuong_duong_hoang_hau_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 'ỷ lan' in t or 'nguyên phi' in t or 'linh nhân' in t: refs.append(REFS['y_lan'])
    if 'lý thánh tông' in t: refs.append(REFS['ly_thanh_tong'])
    if 'lý nhân tông' in t or 'càn đức' in t or 'vua trẻ' in t: refs.append(REFS['ly_nhan_tong'])
    if 'lý thường kiệt' in t or 'như nguyệt' in t or 'chống tống' in t: refs.append(REFS['ly_thuong_kiet'])
    if 'thượng dương' in t: refs.append(REFS['thuong_duong'])
    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: 11th-century Đại Việt under the Lý dynasty, Thăng Long court, Gia Lâm countryside, Buddhist temples, court politics, dân sinh, and anti-Song wartime atmosphere as appropriate.\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 Lý dynasty clothing, architecture, ritual objects, temples, 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 'NGƯỜI CON GÁI HÁI DÂU BƯỚC VÀO LONG MẠCH ĐẠI VIỆT'. Large dramatic portrait of Ỷ Lan from village girl to Linh Nhân Hoàng thái hậu, orchid tree silhouette, Thăng Long palace, Lý dynasty temple, parchment manuscript texture, dark sepia bronze black palette, large readable metallic-gold Vietnamese brush lettering over irregular black ink-splash title panel. Historically grounded 11th-century Đại Việt, 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['y_lan'])]
    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()
