"""3a backfill — 재렌더 없이 기존 background_render manifest 의 실제 첨부 prior_bg 를
production 순수함수(_compose_bg_input_image_ids)로 계산해 DB input_image_ids 를 정정.
직전 실패 canary 의 잘못된 데이터(fp-only + 오타 metadata)를 올바른 [fp,*prior]+lineage
메타로 교체. 커밋 금지(scratchpad). read manifest + write input_image_ids(lineage annotation).
실행: backend/.venv/bin/python scratchpad/p3a_backfill.py
"""
import json
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.core.steps.background_render_step import _compose_bg_input_image_ids  # noqa: E402

PROJ = "a7f80ab9-e97b-420c-a380-3beccb0bcfe5"
EP = "286f3ba4-5738-49b7-a7e4-ce0295fd4352"
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
MF = os.path.join(ROOT, f"projects/{PROJ}/checkpoints/episodes/{EP}"
                  f"/background_render/manifest.json")


def main():
    from sqlalchemy import text
    from app.core.database import SessionLocal

    d = json.load(open(MF))
    groups = d["data"].get("groups", {})
    db = SessionLocal()
    try:
        # bg variant_type -> uuid
        rows = db.execute(text(
            "SELECT variant_type, id, input_image_ids FROM image_asset "
            "WHERE episode_id=:ep AND pipeline_role='background_render' "
            "AND variant_type IS NOT NULL"), {"ep": EP}).fetchall()
        uuid_by_bgid = {r[0]: str(r[1]) for r in rows}
        cur_input = {r[0]: r[2] for r in rows}

        updated = 0
        for bid in sorted(groups):
            g = groups[bid]
            if g.get("status") != "ok":
                continue
            lin = g.get("attached_reference_lineage") or {}
            prior = []
            for b in (lin.get("prior_bg_ids") or []):
                bs = str(b)
                if bs and bs != bid and bs not in prior:
                    prior.append(bs)
            if not prior:
                continue
            reuse = (lin.get("ref_used") == "reused_plate")
            # fp_uuid = 현재 row 가 이미 기록한 input_image_ids[0](step 이 _fp_id_by_canon
            # 로 넣은 fp). 없으면 None.
            fp_uuid = None
            try:
                _cur = json.loads(cur_input.get(bid) or "[]")
                if _cur:
                    fp_uuid = _cur[0]
            except Exception:
                pass
            iids, meta = _compose_bg_input_image_ids(
                prior, fp_uuid, uuid_by_bgid, reuse=reuse)
            meta["backfilled_from_manifest"] = True
            db.execute(text(
                "UPDATE image_asset SET input_image_ids=:iid, "
                "pipeline_metadata_json=:meta "
                "WHERE episode_id=:ep AND pipeline_role='background_render' "
                "AND variant_type=:vt"),
                {"iid": json.dumps(iids), "meta": json.dumps(meta, ensure_ascii=False),
                 "ep": EP, "vt": bid})
            updated += 1
            print(f"{bid}: input_image_ids={iids} kind={meta['lineage_kind']}")
        db.commit()
        print(f"\n★ backfill 완료: {updated} bg 정정")
    finally:
        db.close()


if __name__ == "__main__":
    main()
