#!/usr/bin/env python3
import importlib.util
import json
import time
from pathlib import Path

PROJECT = Path('/data/video-pipeline/Youtube-Video-Maker/Project/01072026-001-Nha-Tay-Son')
BASE = PROJECT / 'scripts_run_step_06_images.py'
LOG = PROJECT / 'logs/step06_missing_serial_retry.log'
MANIFEST = PROJECT / 'logs/step06_missing_serial_manifest.json'

spec = importlib.util.spec_from_file_location('step6', BASE)
step6 = importlib.util.module_from_spec(spec)
spec.loader.exec_module(step6)

def log(msg):
    line = time.strftime('%Y-%m-%d %H:%M:%S ') + msg
    print(line, flush=True)
    with LOG.open('a', encoding='utf-8') as f:
        f.write(line + '\n')

def is_ok(scene_id):
    p = PROJECT / 'images/scenes' / f'{scene_id}.png'
    return p.exists() and p.stat().st_size > 1000

def main():
    LOG.parent.mkdir(parents=True, exist_ok=True)
    LOG.write_text('', encoding='utf-8')
    scenes = json.loads((PROJECT / 'script/scenes.json').read_text(encoding='utf-8'))['scenes']
    refs = step6.load_refs()
    targets = [s for s in scenes if not is_ok(s['scene_id'])]
    log(f'START serial missing retry targets={len(targets)}')
    results = []
    for idx, scene in enumerate(targets, 1):
        sid = scene['scene_id']
        if is_ok(sid):
            results.append({'scene_id': sid, 'status': 'skipped_exists'})
            continue
        final = None
        for attempt in range(1, 5):
            log(f'GENERATE {sid} attempt={attempt} remaining={len(targets)-idx}')
            r = step6.run_one(scene, refs)
            final = r
            if r.get('status') in ('ok', 'skipped_exists') and is_ok(sid):
                log(f"OK {sid} bytes={r.get('bytes')}")
                break
            err = (r.get('error') or '')[-500:].replace('\n', ' | ')
            log(f'FAILED {sid} attempt={attempt} {err}')
            sleep_s = 75 if '429' in (r.get('error') or '') else 30
            time.sleep(sleep_s)
        results.append(final or {'scene_id': sid, 'status': 'failed_no_result'})
        time.sleep(12)
    missing = [s['scene_id'] for s in scenes if not is_ok(s['scene_id'])]
    thumb_results = []
    if not missing:
        log('START thumbnails')
        out_thumbs = PROJECT / 'output/thumbnails'
        out_thumbs.mkdir(parents=True, exist_ok=True)
        for kind, name in [('16x9', 'thumb_16x9_final.png'), ('9x16', 'thumb_9x16_final.png')]:
            for attempt in range(1, 5):
                tr = step6.gen_thumb(kind, out_thumbs / name, refs)
                if tr.get('status') in ('ok', 'skipped_exists'):
                    log(f'THUMB OK {kind}')
                    thumb_results.append(tr)
                    break
                log(f"THUMB FAILED {kind} attempt={attempt} {(tr.get('error') or '')[-500:]}")
                time.sleep(75)
    status = 'completed' if not missing and len(thumb_results) == 2 else 'needs_retry'
    MANIFEST.write_text(json.dumps({'project_id': PROJECT.name, 'status': status, 'targets': len(targets), 'missing': missing, 'results': results, 'thumbnail_results': thumb_results}, ensure_ascii=False, indent=2), encoding='utf-8')
    log(f'DONE status={status} missing={len(missing)} thumbs={len(thumb_results)}')
    if status != 'completed':
        raise SystemExit('needs_retry')

if __name__ == '__main__':
    main()
