"""品牌引用LLM服务测试 - 迁移自 test_llm_adapter.py

原 LLMAdapter (System 3) 已被 BrandCitationLLMService (System 1) 替代。
本文件保留了所有原有的测试场景，使用新的服务接口。
"""
import pytest
from unittest.mock import AsyncMock, patch, MagicMock

from app.services.llm.brand_citation_service import BrandCitationLLMService, BRAND_CITATION_PROMPT
from app.services.llm.base import LLMError


class TestBrandCitationLLMService:
    """品牌引用LLM服务测试（原 LLMAdapter 测试迁移）"""

    @pytest.fixture
    def service(self):
        """创建BrandCitationLLMService实例"""
        return BrandCitationLLMService()

    @pytest.mark.asyncio
    async def test_cited_brand(self, service):
        """测试检测到品牌引用"""
        mock_provider = AsyncMock()
        mock_provider.chat.return_value = MagicMock(
            content='{"cited": true, "position": 1, "citation_text": "XXX是一款非常优秀的品牌产品", "sentiment": "positive", "confidence": 0.95}'
        )
        with patch.object(service, '_get_provider', return_value=mock_provider):
            with patch('app.services.llm.brand_citation_service.settings') as mock_settings:
                mock_settings.ENABLE_LLM = True
                result = await service.query_brand_citation(
                    keyword="AI搜索",
                    brand_name="XXX",
                    brand_aliases=["品牌别名1", "品牌别名2"]
                )
                assert result.cited is True
                assert result.position == 1
                assert result.citation_text == "XXX是一款非常优秀的品牌产品"
                assert result.sentiment == "positive"
                assert result.confidence == 0.95

    @pytest.mark.asyncio
    async def test_not_cited(self, service):
        """测试未检测到品牌引用"""
        mock_provider = AsyncMock()
        mock_provider.chat.return_value = MagicMock(
            content='{"cited": false, "position": null, "citation_text": null, "sentiment": "neutral", "confidence": 0.90}'
        )
        with patch.object(service, '_get_provider', return_value=mock_provider):
            with patch('app.services.llm.brand_citation_service.settings') as mock_settings:
                mock_settings.ENABLE_LLM = True
                result = await service.query_brand_citation(
                    keyword="AI搜索",
                    brand_name="YYY",
                    brand_aliases=[]
                )
                assert result.cited is False
                assert result.position is None
                assert result.citation_text is None
                assert result.sentiment == "neutral"

    @pytest.mark.asyncio
    async def test_sentiment_positive(self, service):
        """测试正面情感"""
        mock_provider = AsyncMock()
        mock_provider.chat.return_value = MagicMock(
            content='{"cited": true, "position": 2, "citation_text": "YYY品牌产品质量非常好，用户口碑极佳", "sentiment": "positive", "confidence": 0.92}'
        )
        with patch.object(service, '_get_provider', return_value=mock_provider):
            with patch('app.services.llm.brand_citation_service.settings') as mock_settings:
                mock_settings.ENABLE_LLM = True
                result = await service.query_brand_citation(
                    keyword="AI搜索",
                    brand_name="YYY",
                    brand_aliases=[]
                )
                assert result.sentiment == "positive"

    @pytest.mark.asyncio
    async def test_sentiment_negative(self, service):
        """测试负面情感"""
        mock_provider = AsyncMock()
        mock_provider.chat.return_value = MagicMock(
            content='{"cited": true, "position": 3, "citation_text": "ZZZ品牌存在质量问题，遭到用户投诉", "sentiment": "negative", "confidence": 0.88}'
        )
        with patch.object(service, '_get_provider', return_value=mock_provider):
            with patch('app.services.llm.brand_citation_service.settings') as mock_settings:
                mock_settings.ENABLE_LLM = True
                result = await service.query_brand_citation(
                    keyword="AI搜索",
                    brand_name="ZZZ",
                    brand_aliases=[]
                )
                assert result.sentiment == "negative"

    @pytest.mark.asyncio
    async def test_parse_error(self, service):
        """测试响应解析错误"""
        mock_provider = AsyncMock()
        mock_provider.chat.return_value = MagicMock(
            content='{"invalid": "response"}'
        )
        with patch.object(service, '_get_provider', return_value=mock_provider):
            with patch('app.services.llm.brand_citation_service.settings') as mock_settings:
                mock_settings.ENABLE_LLM = True
                with pytest.raises(LLMError) as exc_info:
                    await service.query_brand_citation(
                        keyword="AI搜索",
                        brand_name="测试品牌",
                        brand_aliases=[]
                    )
                error_msg = str(exc_info.value)
                assert "响应缺少必需字段" in error_msg or "解析响应失败" in error_msg

    def test_build_prompt(self, service):
        """测试Prompt构建"""
        prompt = service._build_prompt(
            keyword="AI搜索",
            brand_name="测试品牌",
            brand_aliases=["别名1", "别名2"]
        )
        assert "AI搜索" in prompt
        assert "测试品牌" in prompt
        assert "别名1" in prompt
        assert "别名2" in prompt
