"""Unit tests for TranslationService."""

import json
from unittest.mock import MagicMock, patch

import pytest

from src.extraction_v2.translation_service import TranslationService


class TestTranslationService:
    """Tests for TranslationService class."""

    def test_lazy_client_initialization(self):
        """Should initialize client lazily on first use."""
        service = TranslationService()
        assert service._client is None
        assert not service._client_initialized

    @patch("src.extraction_v2.translation_service.AzureOpenAI")
    def test_translate_term_success(self, mock_azure_openai):
        """Should translate term successfully and return translations dict."""
        # Mock LLM response
        mock_response = MagicMock()
        mock_response.choices = [MagicMock()]
        mock_response.choices[0].message.content = json.dumps({
            "ja": "売上",
            "en": "revenue",
            "vi": "doanh thu"
        })

        mock_client = MagicMock()
        mock_client.chat.completions.create.return_value = mock_response
        mock_azure_openai.return_value = mock_client

        service = TranslationService()
        translations, success = service.translate_term("revenue", "en")

        assert success is True
        assert translations["ja"] == "売上"
        assert translations["en"] == "revenue"
        assert translations["vi"] == "doanh thu"

    @patch("src.extraction_v2.translation_service.AzureOpenAI")
    def test_translate_term_with_null_values(self, mock_azure_openai):
        """Should handle null values for untranslatable terms."""
        # Mock LLM response with null values
        mock_response = MagicMock()
        mock_response.choices = [MagicMock()]
        mock_response.choices[0].message.content = json.dumps({
            "ja": "売上",
            "en": "revenue",
            "vi": None  # Untranslatable to Vietnamese
        })

        mock_client = MagicMock()
        mock_client.chat.completions.create.return_value = mock_response
        mock_azure_openai.return_value = mock_client

        service = TranslationService()
        translations, success = service.translate_term("revenue", "en")

        assert success is True
        assert translations["ja"] == "売上"
        assert translations["en"] == "revenue"
        assert translations["vi"] is None

    @patch("src.extraction_v2.translation_service.AzureOpenAI")
    @patch("src.extraction_v2.translation_service.time.sleep")
    def test_translate_term_retry_on_failure(self, mock_sleep, mock_azure_openai):
        """Should retry on failure and return failure status."""
        # Mock LLM to raise exception
        mock_client = MagicMock()
        mock_client.chat.completions.create.side_effect = Exception("API Error")
        mock_azure_openai.return_value = mock_client

        service = TranslationService()
        translations, success = service.translate_term("revenue", "en", max_retries=1)

        assert success is False
        assert translations["ja"] is None
        assert translations["en"] is None
        assert translations["vi"] is None
        # Should have called sleep for backoff
        assert mock_sleep.call_count == 1

    @patch("src.extraction_v2.translation_service.AzureOpenAI")
    def test_translate_term_invalid_json_response(self, mock_azure_openai):
        """Should handle invalid JSON response gracefully."""
        # Mock LLM response with invalid JSON
        mock_response = MagicMock()
        mock_response.choices = [MagicMock()]
        mock_response.choices[0].message.content = "invalid json"

        mock_client = MagicMock()
        mock_client.chat.completions.create.return_value = mock_response
        mock_azure_openai.return_value = mock_client

        service = TranslationService()
        translations, success = service.translate_term("revenue", "en", max_retries=0)

        assert success is False
        assert translations["ja"] is None
        assert translations["en"] is None
        assert translations["vi"] is None
