"""
Bible API Client for Bible-Companion.
Interfaces with external Bible API service to fetch verse translations.
"""

import logging
import httpx
from typing import Dict, List, Optional

logger = logging.getLogger(__name__)


class BibleAPIClient:
    """Client for fetching Bible verses from the Bible API service."""

    def __init__(self, base_url: str = "http://localhost:5000", timeout: int = 10):
        """
        Initialize Bible API client.

        Args:
            base_url: Base URL of Bible API service (e.g., http://localhost:5000 or https://api.example.com)
            timeout: Request timeout in seconds
        """
        self.base_url = base_url.rstrip('/')
        self.timeout = timeout
        self._cache: Dict[str, Dict] = {}

    async def health_check(self) -> bool:
        """
        Check if Bible API is reachable.

        Returns:
            True if API is healthy, False otherwise
        """
        try:
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                response = await client.get(f"{self.base_url}/health")
                return response.status_code == 200
        except Exception as e:
            logger.warning(f"Bible API health check failed: {e}")
            return False

    async def get_translations(self) -> List[Dict]:
        """
        Get list of available Bible translations.

        Returns:
            List of translation dictionaries with id, name, verse_count
        """
        try:
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                response = await client.get(f"{self.base_url}/translations")
                response.raise_for_status()
                data = response.json()
                return data.get('translations', [])
        except Exception as e:
            logger.error(f"Failed to fetch translations: {e}")
            return []

    async def get_verse(
        self,
        book: str,
        chapter: int,
        verse: Optional[int] = None,
        translation: str = "KJV"
    ) -> Optional[Dict]:
        """
        Get a specific verse or verse range.

        Args:
            book: Book name (e.g., "John", "Genesis")
            chapter: Chapter number
            verse: Optional verse number (if None, returns whole chapter)
            translation: Bible translation code (KJV, NKJV, NIV, etc.)

        Returns:
            Verse data with reference and text, or None if not found
        """
        try:
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                url = f"{self.base_url}/verses/{translation}/{book}/{chapter}"
                response = await client.get(url)

                if response.status_code == 404:
                    logger.debug(f"Verse not found: {book} {chapter}:{verse} ({translation})")
                    return None

                response.raise_for_status()
                data = response.json()

                verse_data = data.get('data', {})

                # If specific verse requested, extract it
                if verse is not None:
                    verses = verse_data.get('verses', {})
                    verse_text = verses.get(str(verse))
                    if verse_text:
                        return {
                            'reference': f"{book} {chapter}:{verse}",
                            'text': verse_text,
                            'translation': translation,
                            'book': book,
                            'chapter': chapter,
                            'verse': verse
                        }
                    return None

                # Return whole chapter
                return verse_data

        except Exception as e:
            logger.error(f"Failed to fetch verse {book} {chapter}:{verse}: {e}")
            return None

    async def get_chapter(
        self,
        book: str,
        chapter: int,
        translation: str = "KJV"
    ) -> Optional[Dict]:
        """
        Get all verses for a chapter.

        Args:
            book: Book name
            chapter: Chapter number
            translation: Bible translation code

        Returns:
            Chapter data with all verses, or None if not found
        """
        cache_key = f"{translation}_{book}_{chapter}"
        if cache_key in self._cache:
            return self._cache[cache_key]

        try:
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                url = f"{self.base_url}/verses/{translation}/{book}/{chapter}"
                response = await client.get(url)

                if response.status_code == 404:
                    logger.debug(f"Chapter not found: {book} {chapter} ({translation})")
                    return None

                response.raise_for_status()
                data = response.json()
                chapter_data = data.get('data', {})

                # Cache for future requests
                self._cache[cache_key] = chapter_data

                return chapter_data

        except Exception as e:
            logger.error(f"Failed to fetch chapter {book} {chapter}: {e}")
            return None

    async def search_verses(
        self,
        query: str,
        translation: str = "KJV",
        limit: int = 5
    ) -> List[Dict]:
        """
        Search for verses by keyword.

        Args:
            query: Search term
            translation: Bible translation code
            limit: Maximum results to return

        Returns:
            List of matching verses
        """
        try:
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                url = f"{self.base_url}/search"
                params = {
                    'q': query,
                    'translation': translation,
                    'limit': limit
                }
                response = await client.get(url, params=params)

                if response.status_code == 404:
                    return []

                response.raise_for_status()
                data = response.json()
                return data.get('results', [])

        except Exception as e:
            logger.warning(f"Verse search failed for '{query}': {e}")
            return []

    async def get_verse_in_all_translations(
        self,
        book: str,
        chapter: int,
        verse: int,
        translations: Optional[List[str]] = None
    ) -> Dict[str, str]:
        """
        Get the same verse in multiple translations.

        Args:
            book: Book name
            chapter: Chapter number
            verse: Verse number
            translations: List of translation codes (if None, uses default set)

        Returns:
            Dictionary mapping translation code to verse text
        """
        if translations is None:
            translations = ["KJV", "NKJV", "NIV"]

        results = {}
        for trans in translations:
            verse_data = await self.get_verse(book, chapter, verse, trans)
            if verse_data:
                results[trans] = verse_data['text']

        return results

    def clear_cache(self):
        """Clear the verse cache."""
        self._cache.clear()
        logger.info("Verse cache cleared")
