"""GeneratedQuestion.sub_pattern 字段 + _to_generated_question 透传。"""

from app.question_gen.generator_v2 import CandidateQuestion
from app.question_gen.pipeline_v2 import _to_generated_question
from core.types import GeneratedQuestion


def _candidate() -> CandidateQuestion:
    return CandidateQuestion(
        question_id="v1_Action Recognition_0001",
        video_id="v1",
        task_type="Action Recognition",
        skill_target="M1_AR",
        question="厨师最终采用了哪种烹饪方式？",
        options=("A. 蒸", "B. 炒", "C. 煮", "D. 炸"),
        answer="A",
        source_nodes=("n1", "n2"),
        difficulty="hard",
    )


def test_generated_question_has_sub_pattern_default_none():
    q = GeneratedQuestion(
        question_id="q1",
        video_id="v1",
        task_type="Action Recognition",
        question="?",
        options=("A. x",),
        answer="A",
        source_nodes=("n1",),
        difficulty="easy",
    )
    assert q.sub_pattern is None


def test_to_generated_question_threads_sub_pattern():
    q = _to_generated_question(
        _candidate(),
        family="ACTION_RECOGNITION",
        sub_pattern="premature_evidence_anchoring",
    )
    assert q.sub_pattern == "premature_evidence_anchoring"


def test_to_generated_question_sub_pattern_defaults_none():
    q = _to_generated_question(_candidate(), family="RETRIEVAL")
    assert q.sub_pattern is None


def test_question_to_entry_includes_sub_pattern():
    from tools.generate_questions import _question_to_entry

    q = GeneratedQuestion(
        question_id="v1_Action Recognition_0001",
        video_id="v1",
        task_type="Action Recognition",
        question="?",
        options=("A. 蒸", "B. 炒", "C. 煮", "D. 炸"),
        answer="A",
        source_nodes=("n1",),
        difficulty="hard",
        family="ACTION_RECOGNITION",
        skill_target="M1_AR",
        sub_pattern="temporal_reasoning_failure",
    )
    entry = _question_to_entry(q)
    assert entry["sub_pattern"] == "temporal_reasoning_failure"
    assert entry["question_id"] == "v1_Action Recognition_0001"
    assert entry["options"] == ["A. 蒸", "B. 炒", "C. 煮", "D. 炸"]


def test_append_to_json_writes_sub_pattern(tmp_path):
    from tools.generate_questions import _append_to_json

    q = GeneratedQuestion(
        question_id="v1_Action Recognition_0001",
        video_id="v1",
        task_type="Action Recognition",
        question="?",
        options=("A. 蒸", "B. 炒", "C. 煮", "D. 炸"),
        answer="A",
        source_nodes=("n1",),
        difficulty="hard",
        family="ACTION_RECOGNITION",
        skill_target="M1_AR",
        sub_pattern="temporal_reasoning_failure",
    )
    _append_to_json(tmp_path, q)
    import json

    data = json.loads((tmp_path / "v1.json").read_text(encoding="utf-8"))
    assert data[0]["sub_pattern"] == "temporal_reasoning_failure"


def test_load_benchmark_restores_sub_pattern(tmp_path):
    from app.question_gen.loader import load_benchmark
    import json

    entry = {
        "question_id": "v1_Action Recognition_0001",
        "video_id": "v1",
        "task_type": "Action Recognition",
        "question": "?",
        "options": ["A. 蒸", "B. 炒", "C. 煮", "D. 炸"],
        "answer": "A",
        "source_nodes": ["n1"],
        "difficulty": "hard",
        "family": "ACTION_RECOGNITION",
        "skill_target": "M1_AR",
        "sub_pattern": "temporal_reasoning_failure",
    }
    (tmp_path / "v1.json").write_text(json.dumps([entry]), encoding="utf-8")
    loaded = load_benchmark(tmp_path)
    assert loaded[0].sub_pattern == "temporal_reasoning_failure"


def test_load_benchmark_sub_pattern_defaults_none_when_absent(tmp_path):
    from app.question_gen.loader import load_benchmark
    import json

    entry = {
        "question_id": "v1_Object Recognition_0001",
        "video_id": "v1",
        "task_type": "Object Recognition",
        "question": "?",
        "options": ["A. a", "B. b", "C. c", "D. d"],
        "answer": "A",
        "source_nodes": ["n1"],
        "difficulty": "medium",
    }
    (tmp_path / "v1.json").write_text(json.dumps([entry]), encoding="utf-8")
    loaded = load_benchmark(tmp_path)
    assert loaded[0].sub_pattern is None
