"""P-C batch: stale(input 빈칸) 53 스틸을 (씬,샷) 순으로 재생성 → 가이드/배경/캐릭터 lineage 채움.
검증된 시신/벽갇힘 샷(input 이미 채워짐)은 목록에 없으므로 재-roll 안 됨. 실패는 로그 후 continue."""
import requests, sys, time, csv, json

BASE = "http://localhost:8000"
PID = "a7f80ab9-e97b-420c-a380-3beccb0bcfe5"
CSV = "scratchpad/stale_stills.csv"
LOG = "scratchpad/pc_batch_regen_progress.log"

def log(msg):
    line = f"[{time.strftime('%H:%M:%S')}] {msg}"
    print(line, flush=True)
    with open(LOG, "a") as f:
        f.write(line + "\n")

rows = []
with open(CSV) as f:
    for r in csv.reader(f):
        if len(r) == 3:
            rows.append((r[0], r[1], r[2]))

s = requests.Session()
r = s.post(f"{BASE}/api/v1/auth/login", json={"username": "admin", "password": "admin123"})
if r.status_code != 200:
    log(f"LOGIN FAIL {r.status_code} {r.text[:200]}"); sys.exit(1)
log(f"login ok — {len(rows)} stale stills 재생성 시작")

ok = fail = 0
for i, (sc, sh, still) in enumerate(rows, 1):
    t0 = time.time()
    try:
        r = s.post(f"{BASE}/api/v1/projects/{PID}/stills/{still}/generate-image",
                   json={}, timeout=600)
        dt = time.time() - t0
        if r.status_code == 200:
            d = r.json()
            ok += 1
            log(f"{i}/{len(rows)} S{sc}sh{sh} {still[:8]} OK ({dt:.0f}s) asset={str(d.get('id'))[:8]} status={d.get('status')}")
        else:
            fail += 1
            log(f"{i}/{len(rows)} S{sc}sh{sh} {still[:8]} HTTP{r.status_code} ({dt:.0f}s) {r.text[:200]}")
    except Exception as e:
        fail += 1
        log(f"{i}/{len(rows)} S{sc}sh{sh} {still[:8]} EXC {type(e).__name__}: {str(e)[:200]}")
    time.sleep(1)

log(f"DONE ok={ok} fail={fail} total={len(rows)}")
