"""Tests for WideSutra API client."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

from widesutra import WideSutra


def _mock_response(data: dict) -> MagicMock:  # type: ignore[type-arg]
    """Create a mock httpx response."""
    mock = MagicMock()
    mock.json.return_value = data
    mock.raise_for_status.return_value = None
    return mock


class TestWideSutra:
    """Test WideSutra API client methods."""

    def test_init_default(self) -> None:
        client = WideSutra()
        assert client._client.base_url == "https://widesutra.com/api/v1/sutra/"
        client.close()

    def test_init_custom_base_url(self) -> None:
        client = WideSutra(base_url="http://localhost:8000")
        assert client._client.base_url == "http://localhost:8000/api/v1/sutra/"
        client.close()

    def test_init_custom_timeout(self) -> None:
        client = WideSutra(timeout=30.0)
        assert client._client.timeout.connect == 30.0
        client.close()

    def test_context_manager(self) -> None:
        with WideSutra() as client:
            assert client is not None

    @patch("httpx.Client.get")
    def test_list_collections(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 5, "results": []})
        with WideSutra() as client:
            result = client.list_collections()
        assert result["count"] == 5
        mock_get.assert_called_once()

    @patch("httpx.Client.get")
    def test_list_collections_with_tradition(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 1, "results": []})
        with WideSutra() as client:
            result = client.list_collections(tradition="theravada")
        assert result["count"] == 1

    @patch("httpx.Client.get")
    def test_get_collection(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "name": "Tipitaka",
                "slug": "tipitaka",
                "tradition": "Theravada",
                "text_count": 3500,
            }
        )
        with WideSutra() as client:
            result = client.get_collection("tipitaka")
        assert result["name"] == "Tipitaka"
        assert result["text_count"] == 3500

    @patch("httpx.Client.get")
    def test_list_books(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 15, "results": []})
        with WideSutra() as client:
            result = client.list_books()
        assert result["count"] == 15

    @patch("httpx.Client.get")
    def test_list_books_by_collection(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 10, "results": []})
        with WideSutra() as client:
            result = client.list_books(collection="tipitaka")
        assert result["count"] == 10

    @patch("httpx.Client.get")
    def test_get_book(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "name": "Dhammapada",
                "slug": "dhammapada",
                "pali_name": "Dhammapada",
                "chapter_count": 26,
            }
        )
        with WideSutra() as client:
            result = client.get_book("dhammapada")
        assert result["name"] == "Dhammapada"
        assert result["chapter_count"] == 26

    @patch("httpx.Client.get")
    def test_get_text(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "results": [
                    {
                        "book_slug": "dhammapada",
                        "book_name": "Dhammapada",
                        "chapter_number": 1,
                        "number": 1,
                        "translation_code": "sujato",
                        "text": "Mind is the forerunner of all actions.",
                        "text_pali": "Manopubbangama dhamma...",
                        "reference": "Dhp 1:1",
                    }
                ],
            }
        )
        with WideSutra() as client:
            result = client.get_text("dhammapada", 1, 1)
        assert result["results"][0]["reference"] == "Dhp 1:1"

    @patch("httpx.Client.get")
    def test_search(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "count": 5,
                "results": [{"reference": "SN 56.11", "text": "The Four Noble Truths..."}],
            }
        )
        with WideSutra() as client:
            result = client.search("four noble truths", limit=10)
        assert result["count"] == 5

    @patch("httpx.Client.get")
    def test_list_translations(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 3, "results": []})
        with WideSutra() as client:
            result = client.list_translations()
        assert result["count"] == 3

    @patch("httpx.Client.get")
    def test_get_translation(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "code": "sujato",
                "name": "Bhikkhu Sujato",
                "language": "English",
                "translator": "Bhikkhu Sujato",
            }
        )
        with WideSutra() as client:
            result = client.get_translation("sujato")
        assert result["code"] == "sujato"

    @patch("httpx.Client.get")
    def test_list_figures(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 10, "results": []})
        with WideSutra() as client:
            result = client.list_figures()
        assert result["count"] == 10

    @patch("httpx.Client.get")
    def test_list_figures_with_tradition(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 5, "results": []})
        with WideSutra() as client:
            result = client.list_figures(tradition="theravada")
        assert result["count"] == 5

    @patch("httpx.Client.get")
    def test_get_figure(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "name": "Siddhartha Gautama",
                "slug": "siddhartha-gautama",
                "pali_name": "Siddhattha Gotama",
                "sanskrit_name": "Siddhartha Gautama",
                "title": "The Buddha",
                "tradition": "All traditions",
                "is_buddha": True,
            }
        )
        with WideSutra() as client:
            result = client.get_figure("siddhartha-gautama")
        assert result["name"] == "Siddhartha Gautama"
        assert result["is_buddha"] is True

    @patch("httpx.Client.get")
    def test_list_concepts(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 15, "results": []})
        with WideSutra() as client:
            result = client.list_concepts()
        assert result["count"] == 15

    @patch("httpx.Client.get")
    def test_list_concepts_with_category(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 4, "results": []})
        with WideSutra() as client:
            result = client.list_concepts(category="doctrine")
        assert result["count"] == 4

    @patch("httpx.Client.get")
    def test_get_concept(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "name": "Four Noble Truths",
                "slug": "four-noble-truths",
                "pali_term": "Cattari Ariyasaccani",
                "sanskrit_term": "Catvary Aryasatyani",
                "category": "Doctrine",
                "description": "The foundational teaching of Buddhism.",
            }
        )
        with WideSutra() as client:
            result = client.get_concept("four-noble-truths")
        assert result["name"] == "Four Noble Truths"
        assert result["pali_term"] == "Cattari Ariyasaccani"

    @patch("httpx.Client.get")
    def test_list_topics(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 20, "results": []})
        with WideSutra() as client:
            result = client.list_topics()
        assert result["count"] == 20

    @patch("httpx.Client.get")
    def test_get_topic(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "name": "Meditation",
                "slug": "meditation",
                "pali_term": "Bhavana",
                "verse_count": 85,
            }
        )
        with WideSutra() as client:
            result = client.get_topic("meditation")
        assert result["name"] == "Meditation"

    @patch("httpx.Client.get")
    def test_list_glossary(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response({"count": 150, "results": []})
        with WideSutra() as client:
            result = client.list_glossary()
        assert result["count"] == 150

    @patch("httpx.Client.get")
    def test_get_glossary_term(self, mock_get: MagicMock) -> None:
        mock_get.return_value = _mock_response(
            {
                "term": "Nirvana",
                "slug": "nirvana",
                "pali_word": "Nibbana",
                "sanskrit_word": "Nirvana",
                "definition": "The ultimate goal of Buddhist practice.",
            }
        )
        with WideSutra() as client:
            result = client.get_glossary_term("nirvana")
        assert result["term"] == "Nirvana"
        assert result["pali_word"] == "Nibbana"


class TestWideSutraVersion:
    def test_version(self) -> None:
        from widesutra import __version__

        assert __version__ == "0.1.0"

    def test_version_is_string(self) -> None:
        from widesutra import __version__

        assert isinstance(__version__, str)
