"""사람 판정을 **표의 행으로** 심는 공용 helper — 정본은 표다.

`test_policy_reads_central_acquisition._step` 이 하던 것과 같은 규칙:
  ① 사진은 진짜 파일이어야 한다(투영이 그 내용으로 신원을 만든다)
  ② `verified`/`rejected` 는 표에 행이 있어야 한다 — 줄에 손으로 적은 값은 투영이 덮는다
"""
from __future__ import annotations

import hashlib
import json
import uuid
from pathlib import Path
from typing import Any, Dict, Sequence


def write_photos(root: Path, rows: Sequence[Dict[str, Any]]) -> Dict[str, bytes]:
    """CP 줄의 `chosen.path` 자리마다 **진짜 파일**을 쓴다. 경로 → bytes."""
    out: Dict[str, bytes] = {}
    for r in rows:
        rel = str(((r.get("acquisition") or {}).get("chosen") or {}).get("path") or "")
        if not rel:
            continue
        f = root / rel
        f.parent.mkdir(parents=True, exist_ok=True)
        data = b"\x89PNG\r\n\x1a\n" + hashlib.sha256(rel.encode("utf-8")).digest() * 4
        f.write_bytes(data)
        out[rel] = data
    return out


def seed_verdicts(db, *, cp: Dict[str, Any], root: Path, project_id: str,
                  episode_id: str, want: Dict[str, str],
                  coordinates: Dict[str, str] | None = None) -> int:
    """`want` = research_subject_id → verdict('verified'|'rejected'). 심은 행 수를 돌려준다.

    ★해시는 production `review_inputs_for` 가 낸다 — 여기서 다시 계산하지 않는다.
    """
    from app.models.project import GroundingReferenceFidelityReview as M
    from app.modules.pipeline import grounding_fidelity_review as fr

    coords = coordinates or {"era": "", "region": ""}

    def _sha(row):
        rel = str(((row.get("acquisition") or {}).get("chosen") or {}).get("path") or "")
        f = root / rel
        return hashlib.sha256(f.read_bytes()).hexdigest() if rel and f.is_file() else ""

    now = "2026-09-02T10:00:00+09:00"
    n = 0
    for one in fr.review_inputs_for(cp, project_id=project_id, episode_id=episode_id,
                                    coordinates=coords, sha_of=_sha, strict=False):
        if one.get("fault"):
            continue
        rsid = one["payload"]["research_subject_id"]
        if rsid not in want:
            continue
        verdict = want[rsid]
        db.add(M(id=uuid.uuid4().hex, project_id=project_id, episode_id=episode_id,
                 research_subject_id=rsid, final_id=one["payload"]["final_id"],
                 purpose=one["payload"]["purpose"],
                 acquisition_identity=one["payload"]["acquisition_identity"],
                 image_sha256=one["payload"]["image_sha256"],
                 era=coords["era"], region=coords["region"],
                 review_input_json=fr.canonical_input(one["payload"]),
                 review_input_hash=one["hash"], verdict=verdict, reason="",
                 reviewer_actor="사람", reviewed_at=now,
                 review_contract_version=fr.REVIEW_CONTRACT_VERSION,
                 observed_json="{}", supersedes_id=None,
                 idempotency_key=f"{one['hash']}:{verdict}", created_at=now))
        n += 1
    db.commit()
    return n


def load_frozen_central_cp() -> Dict[str, Any]:
    """canary ① 의 **실물** 중앙 CP (21줄 · 2026-09-02 얼림)."""
    p = Path(__file__).resolve().parent / "fixtures" / "canary_cp" / "reference_acquisition.json"
    return json.loads(p.read_text(encoding="utf-8"))
