"""visual_world_rules 모듈 테스트."""

from unittest.mock import patch


def test_extract_visual_rules_returns_dict_with_rules():
    """extract_visual_rules가 rules 키를 포함하는 dict를 반환."""
    from app.modules.pipeline.visual_world_rules import extract_visual_rules

    mock_result = {
        "rules": [
            {
                "rule_type": "possession",
                "description": "소울라이드 시 대상의 외형으로 그린다",
                "visual_guideline": "빙의된 인물의 얼굴/체형을 사용, 빙의자의 외형 없음",
            }
        ],
        "era": "현대",
        "region": "대한민국",
    }

    with patch("app.modules.pipeline.visual_world_rules.call_structured") as mock_call:
        mock_call.return_value = mock_result
        result = extract_visual_rules("시나리오 전문 텍스트")
        assert isinstance(result, dict)
        assert "rules" in result
        assert len(result["rules"]) == 1
        assert result["rules"][0]["rule_type"] == "possession"
        assert result["era"] == "현대"
        assert result["region"] == "대한민국"


def test_extract_visual_rules_loads_external_prompt():
    """extract_visual_rules가 외부 프롬프트 파일을 로드하는지 확인."""
    from app.modules.pipeline.visual_world_rules import extract_visual_rules

    mock_result = {"rules": [], "era": "현대", "region": "한국"}

    with patch("app.modules.pipeline.visual_world_rules.call_structured") as mock_call, \
         patch("app.modules.pipeline.visual_world_rules.load_prompt") as mock_prompt, \
         patch("app.modules.pipeline.visual_world_rules.load_schema") as mock_schema:
        mock_call.return_value = mock_result
        mock_prompt.return_value = "시스템 프롬프트"
        mock_schema.return_value = {"type": "object", "properties": {}}
        extract_visual_rules("전문")
        mock_prompt.assert_called_once_with("visual_world_rules", "system")
        mock_schema.assert_called_once_with("visual_world_rules", "rules_schema")


def test_extract_visual_rules_passes_episode_summary():
    """extract_visual_rules가 episode_summary를 user_prompt에 포함하는지 확인."""
    from app.modules.pipeline.visual_world_rules import extract_visual_rules

    mock_result = {"rules": [], "era": "조선시대", "region": "한반도"}

    with patch("app.modules.pipeline.visual_world_rules.call_structured") as mock_call:
        mock_call.return_value = mock_result
        extract_visual_rules(
            fulltext="시나리오 전문",
            episode_summary="에피소드 요약 텍스트",
        )
        mock_call.assert_called_once()
        call_kwargs = mock_call.call_args
        # call_structured는 keyword arguments로 호출됨
        user_prompt = call_kwargs.kwargs.get("user_prompt") or call_kwargs[1].get("user_prompt", "")
        if not user_prompt:
            # positional이 아닌 keyword로 전달될 수 있음
            for arg in call_kwargs.args:
                if isinstance(arg, str) and "에피소드 요약" in arg:
                    user_prompt = arg
                    break
            if not user_prompt:
                user_prompt = call_kwargs.kwargs.get("user_prompt", "")
        assert "에피소드 요약 텍스트" in user_prompt
        assert "시나리오 전문" in user_prompt
