"""W21B-wave-4 A2: background_prompt v11 marker-legibility guidance.

v11 = v10 contract verbatim + Base markers 블록에 marker legibility(legibility=low
→ 도면 glyph 대신 label 로 정체 판단) guidance 1줄. schema/output shape v10 동일.
opt-in selector, production default 미변경(여전히 "6"). LLM/image/VLM/DB I/O 0.
"""
from __future__ import annotations

from app.modules.pipeline.background_prompt import (
    PROMPT_VERSION_MAP,
    build_bg_user_prompt,
    resolve_prompt_version,
)
from app.modules.prompt_loader import load_prompt, load_schema


_V11_PACK_NAME = "11.202605300939"


def _bg_spec(surface_role: str = "interior_room"):
    return {
        "bg_id": "L05B07",
        "loc_id": "L05",
        "sub_location": "rooftop room interior",
        "state_label_raw": "day interior plate",
        "surface_role": surface_role,
        "applies_to_shots": ["S5_Shot7"],
    }


# base markers 에 legibility 메타 carry (overlay payload A2 산출 형태).
_OVERLAY = {
    "bg_id": "L05B07",
    "fp_id": "fp_l05_main",
    "use_numbered_elements": [1, 4],
    "ignore_numbered_elements": [3],
    "base_markers_to_reference": [
        {
            "number": 1,
            "label": "shared living zone",
            "category": "area",
            "position_hint": "center",
            "base_layer_decision": "base_structural_unit",
            "render_role": "structural_skeleton",
            "top_down_legibility": "clear",
        },
        {
            "number": 4,
            "label": "private sleeping zone behind curtain",
            "category": "area",
            "position_hint": "upper left",
            "base_layer_decision": "base_structural_unit",
            "render_role": "structural_skeleton",
            "top_down_legibility": "low",
        },
    ],
    "transient_markers_to_describe": [
        {
            "number": 3,
            "label": "scattered debris",
            "category": "prop",
            "position_hint": "north wall floor",
            "base_layer_decision": "state_overlay_plot_cue",
            "render_role": "not_applicable",
            "top_down_legibility": "not_applicable",
        }
    ],
    "ignored_state_overlay_markers": [],
    "target_unit_marker_numbers": [1, 4],
    "dominant_target_unit_marker_number": None,
    "clean_background_expected": False,
    "diagnostics": [],
}


def test_v11_selector_resolves_pack_name():
    assert PROMPT_VERSION_MAP["11"] == _V11_PACK_NAME
    assert resolve_prompt_version("11") == _V11_PACK_NAME


def test_v11_pack_adds_legibility_guidance_keeps_v10_shape():
    system = load_prompt("background_prompt", "system", version=_V11_PACK_NAME)
    user_template = load_prompt(
        "background_prompt", "user_template", version=_V11_PACK_NAME,
    )
    schema = load_schema("background_prompt", "schema", version=_V11_PACK_NAME)

    # 새 guidance 존재.
    assert "Marker legibility (W21B-wave-4)" in system
    assert "legibility=low" in system
    # v10 contract 보존 (screen guard / template / shape unchanged).
    assert "news anchor" in system
    assert "{transient_markers_block}" not in user_template
    assert set(schema["required"]) == {
        "bg_id",
        "t2i_prompt",
        "ref_guide",
        "shot_guides",
        "objects_owned_by_background",
    }


def test_v11_build_surfaces_legibility_and_keeps_purity():
    rendered = build_bg_user_prompt(
        bg_spec=_bg_spec(),
        floor_plan_path="/tmp/fp_l05_main.png",
        prior_bg_paths=[],
        scene_segments=[
            {"scene_index": 5, "heading": "probe", "text": "VERBATIM_SCENE_PROBE_LINE"}
        ],
        visual_world_rules="regional world rule body",
        source_language="ko",
        prompt_version="11",
        overlay_payload=_OVERLAY,
    )
    # render_role + legibility 가 둘 다 surface (not_applicable 만 생략).
    assert (
        "1. shared living zone [area, structural_skeleton, legibility=clear] — center"
    ) in rendered
    assert (
        "4. private sleeping zone behind curtain "
        "[area, structural_skeleton, legibility=low] — upper left"
    ) in rendered
    # v10 purity 보존: transient label / scene 본문 누설 X.
    assert "scattered debris" not in rendered
    assert "VERBATIM_SCENE_PROBE_LINE" not in rendered
    assert "surface_role: interior_room" in rendered


def test_v11_fp_less_exterior_allows_missing_overlay():
    rendered = build_bg_user_prompt(
        bg_spec=_bg_spec("exterior_plate"),
        floor_plan_path="",
        prior_bg_paths=[],
        scene_segments=[],
        visual_world_rules="regional exterior rule",
        source_language="ko",
        prompt_version="11",
        overlay_payload=None,
    )
    assert "surface_role: exterior_plate" in rendered
    assert "fp-less surface plate" in rendered
