"""summarizer 모듈 테스트"""

from unittest.mock import MagicMock, patch

import pytest

from youtube_pipeline.summarizer import (
    YOUTUBE_SUMMARY_PROMPT,
    SummaryResult,
    generate_embedding,
    generate_summary,
)


class TestSummaryResult:
    def test_dataclass_fields(self):
        result = SummaryResult(summary_text="요약", has_numeric_warnings=True)
        assert result.summary_text == "요약"
        assert result.has_numeric_warnings is True


class TestGenerateSummary:
    @patch("youtube_pipeline.summarizer._init_genai")
    def test_returns_summary_result(self, mock_init):
        mock_model = MagicMock()
        mock_response = MagicMock()
        mock_response.text = "## 1. 핵심 요약\n보험 관련 내용입니다."
        mock_model.generate_content.return_value = mock_response
        mock_init.return_value = mock_model

        result = generate_summary("테스트 자막 내용")
        assert isinstance(result, SummaryResult)
        assert "핵심 요약" in result.summary_text
        assert result.has_numeric_warnings is False

    @patch("youtube_pipeline.summarizer._init_genai")
    def test_detects_numeric_warnings(self, mock_init):
        mock_model = MagicMock()
        mock_response = MagicMock()
        mock_response.text = "보험료가 30만원이고 환급률 80%입니다."
        mock_model.generate_content.return_value = mock_response
        mock_init.return_value = mock_model

        result = generate_summary("테스트")
        assert result.has_numeric_warnings is True

    @patch("youtube_pipeline.summarizer._init_genai")
    def test_retries_on_failure(self, mock_init):
        mock_model = MagicMock()
        mock_model.generate_content.side_effect = [
            Exception("rate limit"),
            MagicMock(text="성공한 요약"),
        ]
        mock_init.return_value = mock_model

        with patch("youtube_pipeline.summarizer.time.sleep"):
            result = generate_summary("테스트")
        assert result.summary_text == "성공한 요약"

    @patch("youtube_pipeline.summarizer._init_genai")
    def test_raises_after_max_retries(self, mock_init):
        mock_model = MagicMock()
        mock_model.generate_content.side_effect = Exception("persistent error")
        mock_init.return_value = mock_model

        with patch("youtube_pipeline.summarizer.time.sleep"):
            with pytest.raises(RuntimeError, match="최대 재시도 초과"):
                generate_summary("테스트")


class TestGenerateEmbedding:
    @patch("youtube_pipeline.summarizer.genai.embed_content")
    @patch("youtube_pipeline.summarizer.genai.configure")
    def test_returns_embedding_list(self, mock_configure, mock_embed):
        mock_embed.return_value = {"embedding": [0.1] * 768}
        result = generate_embedding("테스트 텍스트")
        assert len(result) == 768
        assert all(isinstance(v, float) for v in result)

    @patch("youtube_pipeline.summarizer.genai.embed_content")
    @patch("youtube_pipeline.summarizer.genai.configure")
    def test_truncates_long_text(self, mock_configure, mock_embed):
        mock_embed.return_value = {"embedding": [0.1] * 768}
        long_text = "x" * 10000
        generate_embedding(long_text)
        call_args = mock_embed.call_args
        assert (
            len(call_args.kwargs.get("content", call_args[1].get("content", "")))
            <= 8000
        )


class TestSummaryPrompt:
    def test_contains_key_sections(self):
        assert "핵심 요약" in YOUTUBE_SUMMARY_PROMPT
        assert "설계사" in YOUTUBE_SUMMARY_PROMPT
        assert "약관" in YOUTUBE_SUMMARY_PROMPT
        assert "수치" in YOUTUBE_SUMMARY_PROMPT
