"""Tests for the Phase 1.3 QueryDecomposer component."""

import json
from typing import List

import pytest

from app.services.query_decomposer import QueryDecomposer


class MockLLMClient:
    def __init__(self, response: str):
        self._response = response
        self.last_prompt = None
        self.last_step_name = None

    async def complete(self, prompt: str, temperature: float = 0.7, step_name: str = "LLM") -> str:
        self.last_prompt = prompt
        self.last_step_name = step_name
        return self._response


async def test_decompose_valid_json():
    llm = MockLLMClient('["alpha", "beta", "gamma"]')
    decomposer = QueryDecomposer(llm)
    result: List[str] = await decomposer.decompose("What are keywords for X?")
    assert result == ["alpha", "beta", "gamma"]
    assert llm.last_prompt == "Given question: 'What are keywords for X?', extract key search keywords as JSON array"


async def test_decompose_empty_question_returns_empty():
    llm = MockLLMClient('["should_not_be_used"]')
    decomposer = QueryDecomposer(llm)
    result = await decomposer.decompose("")
    assert result == []
    assert llm.last_prompt is None


async def test_decompose_invalid_json_returns_empty():
    llm = MockLLMClient("not-json")
    decomposer = QueryDecomposer(llm)
    result = await decomposer.decompose("Question?")
    assert result == []


async def test_decompose_non_list_json_returns_empty():
    llm = MockLLMClient("{\"a\": 1}")
    decomposer = QueryDecomposer(llm)
    result = await decomposer.decompose("Question?")
    assert result == []


async def test_decompose_mixed_types_coerced_to_strings():
    llm = MockLLMClient('["a", 2, null]')
    decomposer = QueryDecomposer(llm)
    result = await decomposer.decompose("Question?")
    assert result == ["a", "2", "None"]


async def test_decompose_json_in_markdown_code_block():
    llm = MockLLMClient('```json\n["project", "manager", "limits"]\n```')
    decomposer = QueryDecomposer(llm)
    result = await decomposer.decompose("What are the limits?")
    assert result == ["project", "manager", "limits"]


async def test_decompose_json_in_plain_code_block():
    llm = MockLLMClient('```\n["alpha", "beta"]\n```')
    decomposer = QueryDecomposer(llm)
    result = await decomposer.decompose("Keywords?")
    assert result == ["alpha", "beta"]
