import pytest
from app.worker import generate_job_summary_llm, clean_json_response
from app.db.models.transaction import Transaction
from google import genai
from unittest.mock import MagicMock, patch


def test_clean_json_response_markdown():
    # Test stripping markdown code fences
    dirty_json = '```json\n{"key": "value"}\n```'
    assert clean_json_response(dirty_json) == '{"key": "value"}'

    # Test stripping markdown code fences with conversational prefix
    dirty_conversational = (
        'Here is the data:\n```\n{"key": "value"}\n```\nHope it helps.'
    )
    assert clean_json_response(dirty_conversational) == '{"key": "value"}'


@pytest.mark.asyncio
async def test_generate_job_summary_llm_success():
    # 1. Setup mock transactions
    t1 = Transaction(
        merchant="Zomato",
        amount=100.0,
        currency="USD",
        category="Food",
        is_anomaly=False,
    )
    t2 = Transaction(
        merchant="Ola",
        amount=2500.0,
        currency="INR",
        category="Transport",
        is_anomaly=True,
        anomaly_reason="Outlier",
    )
    tx_list = [t1, t2]

    # 2. Mock client and return json
    mock_client = MagicMock(spec=genai.Client)
    mock_interaction = MagicMock()
    mock_interaction.output_text = """
    ```json
    {
      "total_spend_by_currency": {"USD": 100.0, "INR": 2500.0},
      "top_3_merchants": {"Ola": 30.12, "Zomato": 100.0},
      "anomaly_count": 1,
      "spending_narrative": "Cohesive two sentence summary of spendings. Mostly food and transit.",
      "risk_level": "Medium"
    }
    ```
    """
    mock_client.interactions.create.return_value = mock_interaction

    # 3. Call and assert
    result = await generate_job_summary_llm(mock_client, tx_list)
    assert result is not None
    assert result.anomaly_count == 1
    assert result.risk_level == "Medium"
    assert result.total_spend_by_currency["USD"] == 100.0
    assert result.total_spend_by_currency["INR"] == 2500.0
    assert "Ola" in result.top_3_merchants


@pytest.mark.asyncio
async def test_generate_job_summary_llm_retry_failure():
    mock_client = MagicMock(spec=genai.Client)
    mock_client.interactions.create.side_effect = Exception("API Key Expired")

    tx_list = [Transaction(merchant="Test", amount=1.0, currency="USD")]

    # Patch sleep to execute instantly
    with patch("asyncio.sleep", return_value=None):
        result = await generate_job_summary_llm(mock_client, tx_list)

    assert result is None
