"""D6 R3 N1 — scene_detail chain 변경 0 검증 (unit-style).

ctx.chain_bg_id_by_shot[(si, shi)] (D6 의 L##B## 형식) 가
  → _derive_card_inputs_from_ctx (`detail_steps.py:432`)
  → build_render_prompt_card (`render_prompt_card.py`)
  → render_prompt_card.background_binding.bg_id
chain 으로 pass-through 되는지 unit-level 검증.

scene_detail step 자체에는 D6 코드 변경 0 (T5 의 manifest stamp + schema_version
bump 만). bg_id 형식 변경 (D4 의 bg_* → D6 의 L##B##) 은 chain 의 producer
(master_plan / chain_bg loader) 변경에서 자동 cascading.

spec: docs/superpowers/specs/2026-05-09-deterministic-bg-id-and-catalog-lineage.md
plan: T6 (unit-style pivot — d6_episode fixture 의존 제거)
"""
from __future__ import annotations

from types import SimpleNamespace


def _make_fake_ctx(bg_id: str = "L09B01"):
    """detail_steps._derive_card_inputs_from_ctx 가 읽는 모든 ctx attribute 의
    minimal 합법 fake. (si=1, shi=1) 한 shot 만 채움.

    `chain_bg_owned_by_shot` 는 명시 [] (None 이면 builder 가 contract violation
    raise — `detail_steps.py:442-451`).
    """
    return SimpleNamespace(
        shot_director_ve={(1, 1): ["C01"]},
        scene_visible={1: ["C01"]},
        outlook_data=None,
        staging_map={"1_1": {
            "camera_direction": "medium shot",
            # framing_scale enum SOT v1 (2026-05-15): helper read fail-fast 정합.
            "framing_scale": "medium",
            "lighting_mood": "warm",
            # Area C (2026-05-12) — required by build_id_policy. 빈 list =
            # 비-재현면 shot (applies=False).
            "key_bg_elements": [],
            # Area #1 W5 (2026-05-16) — shot_staging v12 top-level required
            # field. helper SOT graceful empty.
            "subject_reference_policy": [],
        }},
        chain_bg_id_by_shot={(1, 1): bg_id},
        chain_bg_owned_by_shot={(1, 1): []},
        chain_bg_camera_meta_by_shot={},
        chain_bg_guide_by_shot={},
        fixed_elements_by_scene={},
        dependencies=[],
        shot_scenes_map={},
    )


def test_chain_bg_id_lnnbnn_passes_through_to_background_binding(monkeypatch):
    """ctx.chain_bg_id_by_shot[(1,1)]='L09B01' → RPC.background_binding.bg_id='L09B01'."""
    from app.core.steps.detail_steps import _derive_card_inputs_from_ctx
    from app.core.steps.render_prompt_card import (
        BG_MODE_REF_ATTACHED,
        build_render_prompt_card,
    )

    monkeypatch.setattr("app.core.config.settings.background_mode", "on")

    ctx = _make_fake_ctx(bg_id="L09B01")
    seg = {"index": 1, "scene_index": 1, "text": "scene segment text"}
    shot_info = {
        "shot_index": 1,
        "camera_direction": "medium shot",
        "primary_subject": "the subject",
    }

    inputs = _derive_card_inputs_from_ctx(ctx=ctx, seg=seg, shot_info=shot_info)
    assert inputs["bg_id"] == "L09B01", "ctx → inputs pass-through 깨짐"

    inputs.pop("ctx", None)  # builder 시그니처 외 — splat 전 strip
    card = build_render_prompt_card(**inputs)
    bb = card["background_binding"]
    assert bb["bg_id"] == "L09B01", f"binding bg_id drift: {bb!r}"
    assert bb["mode"] == BG_MODE_REF_ATTACHED, (
        f"bg_on + bg_id present + non-close framing → ref_attached, "
        f"got {bb['mode']!r}"
    )


def test_render_prompt_card_does_not_emit_deprecated_background_binding_intent(
    monkeypatch,
):
    """R2 의 폐기된 schema field background_binding_intent 가 RPC 에 없음.

    D6 spec R3 N1 — scene_detail prompt 는 background_binding_intent 같은
    LLM-emitted intent field 를 다시 도입하지 않음 (R2 초안에서 폐기됨).
    """
    from app.core.steps.detail_steps import _derive_card_inputs_from_ctx
    from app.core.steps.render_prompt_card import build_render_prompt_card

    monkeypatch.setattr("app.core.config.settings.background_mode", "on")

    ctx = _make_fake_ctx(bg_id="L09B01")
    seg = {"index": 1, "scene_index": 1, "text": "scene segment text"}
    shot_info = {
        "shot_index": 1,
        "camera_direction": "medium shot",
        "primary_subject": "the subject",
    }

    inputs = _derive_card_inputs_from_ctx(ctx=ctx, seg=seg, shot_info=shot_info)
    inputs.pop("ctx", None)
    card = build_render_prompt_card(**inputs)
    assert "background_binding_intent" not in card, (
        "R2 폐기 schema 가 부활됨 (R3 N1 위반)"
    )
