#!/usr/bin/env python3
import json
import os
import subprocess
import sys
from datetime import datetime
from pathlib import Path

PROJECT = Path('/data/video-pipeline/Youtube-Video-Maker/Project/31052026-001-Nguyen-Hue-Quang-Trung')
PLAN_PATH = PROJECT / 'script/character_reference_plan.json'
GEN_SCRIPT = Path('/home/hermes/.hermes/skills/media/gen-img-gpt/scripts/gen_img_gpt.py')
LOG_PATH = PROJECT / 'logs/step05_character_refs_run.log'
MANIFEST_PATH = PROJECT / 'logs/step05_character_refs_manifest.json'


def log(msg: str) -> None:
    LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
    line = f"[{datetime.now().isoformat(timespec='seconds')}] {msg}"
    print(line, flush=True)
    with LOG_PATH.open('a', encoding='utf-8') as fh:
        fh.write(line + '\n')


def main() -> int:
    plan = json.loads(PLAN_PATH.read_text(encoding='utf-8'))
    if not os.environ.get('GEN_IMG_API_KEY'):
        plan['approval_status'] = 'blocked_missing_GEN_IMG_API_KEY'
        PLAN_PATH.write_text(json.dumps(plan, ensure_ascii=False, indent=2), encoding='utf-8')
        log('Blocked: GEN_IMG_API_KEY is missing')
        return 2
    results = []
    for ref in plan['references']:
        out = PROJECT / ref['output_path']
        out.parent.mkdir(parents=True, exist_ok=True)
        if out.exists() and out.stat().st_size > 1000:
            ref['status'] = 'generated_pending_approval'
            results.append({'character_name': ref['character_name'], 'status': 'skipped_existing', 'output_path': str(out)})
            log(f"Skip existing {ref['character_name']} -> {out}")
            continue
        cmd = [sys.executable, str(GEN_SCRIPT), '--prompt', ref['prompt'], '--output', str(out), '--size', 'auto', '--quality', 'auto', '--background', 'auto', '--image-detail', 'high', '--output-format', 'png', '--n', '1']
        log(f"Generating {ref['character_name']} -> {out}")
        proc = subprocess.run(cmd, text=True, capture_output=True, timeout=420)
        if proc.returncode != 0:
            ref['status'] = 'failed'
            ref['error'] = (proc.stderr or proc.stdout)[-2000:]
            results.append({'character_name': ref['character_name'], 'status': 'failed', 'returncode': proc.returncode, 'error': ref['error']})
            log(f"FAILED {ref['character_name']}: {ref['error'][:500]}")
            plan['approval_status'] = 'generation_failed'
            PLAN_PATH.write_text(json.dumps(plan, ensure_ascii=False, indent=2), encoding='utf-8')
            MANIFEST_PATH.write_text(json.dumps({'status': 'failed', 'results': results}, ensure_ascii=False, indent=2), encoding='utf-8')
            return 1
        if not out.exists() or out.stat().st_size < 1000:
            ref['status'] = 'failed_empty_output'
            results.append({'character_name': ref['character_name'], 'status': 'failed_empty_output'})
            log(f"FAILED empty output for {ref['character_name']}")
            return 1
        ref['status'] = 'generated_pending_approval'
        ref['generated_at'] = datetime.now().isoformat(timespec='seconds')
        results.append({'character_name': ref['character_name'], 'status': 'generated_pending_approval', 'output_path': str(out), 'bytes': out.stat().st_size})
        PLAN_PATH.write_text(json.dumps(plan, ensure_ascii=False, indent=2), encoding='utf-8')
        log(f"Generated {ref['character_name']} bytes={out.stat().st_size}")
    plan['approval_status'] = 'pending_human_approval'
    plan['validation']['all_references_generated'] = all((PROJECT / r['output_path']).exists() for r in plan['references'])
    plan['validation']['required_references_generated'] = all((PROJECT / r['output_path']).exists() for r in plan['references'] if r['priority'] == 'required')
    PLAN_PATH.write_text(json.dumps(plan, ensure_ascii=False, indent=2), encoding='utf-8')
    MANIFEST_PATH.write_text(json.dumps({'status': 'pending_human_approval', 'results': results}, ensure_ascii=False, indent=2), encoding='utf-8')
    log('Step 05 reference generation complete; pending human approval')
    return 0


if __name__ == '__main__':
    raise SystemExit(main())
