"""HTTP API client for wideholy.com REST endpoints.

Requires the ``api`` extra: ``pip install wideholy[api]``

Usage::

    from wideholy.api import WideHoly

    with WideHoly() as client:
        votd = client.verse_of_the_day("bible")
        result = client.compare("bible:genesis.1.1", "quran:al-fatihah.1")
        suggestions = client.search_suggest("love")
"""

from __future__ import annotations

from typing import Any

import httpx

VALID_RELIGIONS = ("bible", "quran", "torah", "gita", "sutra")


class WideHoly:
    """Cross-religion scripture search and comparison.

    Provides typed access to all wideholy.com hub API endpoints including
    verse of the day, random verse, cross-religion comparison, search
    suggestions, topic verses, religious calendar, and commentary.

    Args:
        base_url: API base URL. Defaults to ``https://wideholy.com``.
        timeout: Request timeout in seconds. Defaults to ``10.0``.
    """

    def __init__(
        self,
        base_url: str = "https://wideholy.com",
        timeout: float = 10.0,
    ) -> None:
        self._client = httpx.Client(
            base_url=f"{base_url.rstrip('/')}/api/v1/",
            timeout=timeout,
        )

    def _get(self, path: str, **params: Any) -> dict[str, Any]:
        resp = self._client.get(
            path,
            params={k: v for k, v in params.items() if v is not None},
        )
        resp.raise_for_status()
        result: dict[str, Any] = resp.json()
        return result

    # -- 1. Verse of the Day --------------------------------------------------

    def verse_of_the_day(
        self,
        religion: str = "bible",
        date: str | None = None,
    ) -> dict[str, Any]:
        """Get the verse of the day for a religion.

        Returns a curated verse, deterministic per religion per date.

        Args:
            religion: Religion key (bible, quran, torah, gita, sutra).
            date: Date in YYYY-MM-DD format. Defaults to today.

        Returns:
            Dict with reference, text, translation, book, chapter, verse, date.
        """
        return self._get("verse-of-the-day/", religion=religion, date=date)

    # -- 2. Random Verse ------------------------------------------------------

    def random_verse(self, religion: str | None = None) -> dict[str, Any]:
        """Get a random verse, optionally filtered by religion.

        Args:
            religion: Religion key. If None, picks a random religion.

        Returns:
            Dict with religion, reference, text, translation, book, chapter, verse.
        """
        return self._get("random/", religion=religion)

    # -- 3. Compare Verses ----------------------------------------------------

    def compare(self, ref_a: str, ref_b: str) -> dict[str, Any]:
        """Compare two verses side-by-side (same or cross-religion).

        Use ``religion:ref`` format for cross-religion comparison.

        Args:
            ref_a: First verse reference (e.g. ``"bible:genesis.1.1"``).
            ref_b: Second verse reference (e.g. ``"quran:al-fatihah.1"``).

        Returns:
            Dict with verse_a, verse_b, same_religion.
        """
        return self._get("compare/", a=ref_a, b=ref_b)

    # -- 4. Search Suggest ----------------------------------------------------

    def search_suggest(
        self,
        query: str,
        religion: str | None = None,
    ) -> dict[str, Any]:
        """Autocomplete suggestions across religions.

        Returns topic, person, and glossary term suggestions matching the query.

        Args:
            query: Search query prefix (minimum 2 characters).
            religion: Filter to a specific religion.

        Returns:
            Dict with suggestions list (text, type, religion, url).
        """
        return self._get("search/suggest/", q=query, religion=religion)

    # -- 5. Topic Verses ------------------------------------------------------

    def topic_verses(self, topic: str) -> dict[str, Any]:
        """Get verses for a topic across all religions.

        Args:
            topic: Topic slug (e.g. ``"love"``, ``"creation"``, ``"prayer"``).

        Returns:
            Dict with topic, religions_found, verses (per-religion data).
        """
        return self._get(f"topics/{topic}/verses/")

    # -- 6. Cross-Religion Topic ----------------------------------------------

    def cross_religion(self, topic: str) -> dict[str, Any]:
        """Get cross-religion comparison for a universal spiritual theme.

        Args:
            topic: Topic key (e.g. ``"creation"``, ``"prayer"``, ``"love"``).

        Returns:
            Dict with topic, title, summary, religions (per-religion verses and summaries).
        """
        return self._get(f"cross-religion/{topic}/")

    # -- 7. Religious Calendar ------------------------------------------------

    def calendar(
        self,
        religion: str | None = None,
        year: int | None = None,
        month: int | None = None,
    ) -> dict[str, Any]:
        """Get religious calendar events.

        Args:
            religion: Filter by religion key.
            year: Year (default: 2026).
            month: Month number (1-12).

        Returns:
            Dict with year, month, religion, events list.
        """
        return self._get("calendar/", religion=religion, year=year, month=month)

    # -- 8. Commentary --------------------------------------------------------

    def commentary(self, verse_ref: str) -> dict[str, Any]:
        """Get commentary for a verse.

        Supports Quran (tafsir), Torah (Rashi), and Gita commentaries.

        Args:
            verse_ref: Verse reference (e.g. ``"quran:al-fatihah.1"``).

        Returns:
            Dict with verse_ref, religion, commentaries list (source, author, text).
        """
        return self._get(f"commentary/{verse_ref}/")

    # -- Lifecycle ------------------------------------------------------------

    def close(self) -> None:
        """Close the underlying HTTP client."""
        self._client.close()

    def __enter__(self) -> WideHoly:
        return self

    def __exit__(self, *_: object) -> None:
        self.close()
