"""
Google Gemini / Vertex AI client for Bible-Companion.
"""

import logging
import os
from typing import List, Dict
import httpx

logger = logging.getLogger(__name__)


class GeminiClient:
    """
    Async client for Google Gemini API or Vertex AI.
    """

    def __init__(self, api_key: str, model: str = "gemini-2.0-flash"):
        """
        Initialize Gemini client.

        Args:
            api_key: API key for Google AI Studio or Vertex AI
            model: Gemini model name (default: gemini-2.0-flash)
        """
        self.api_key = api_key
        self.model = model
        self.timeout = httpx.Timeout(30.0)

        self.use_vertex = os.getenv("USE_VERTEX", "false").lower() == "true"
        self.vertex_project = os.getenv("VERTEX_PROJECT_ID", "")
        self.vertex_location = os.getenv("VERTEX_LOCATION", "us-central1")

        if self.use_vertex:
            self.base_url = (
                f"https://{self.vertex_location}-aiplatform.googleapis.com/v1/projects/"
                f"{self.vertex_project}/locations/{self.vertex_location}/publishers/google/models"
            )
        else:
            self.base_url = "https://generativelanguage.googleapis.com/v1beta"

        logger.info(
            f"✅ GeminiClient initialized: model={self.model}, use_vertex={self.use_vertex}, "
            f"location={self.vertex_location}"
        )

    async def generate(
        self,
        messages: List[Dict[str, str]],
        temperature: float = 0.7,
        max_tokens: int = 512,
        **kwargs
    ) -> str:
        """
        Generate response from Gemini model.
        """
        system_prompt = None
        contents = []

        for msg in messages:
            role = msg.get("role", "user")
            content = msg.get("content", "")

            if role == "assistant":
                role = "model"
            elif role == "system":
                system_prompt = content
                continue

            contents.append({
                "role": role,
                "parts": [{"text": content}]
            })

        payload = {
            "contents": contents,
            "generationConfig": {
                "temperature": temperature,
                "maxOutputTokens": max_tokens
            }
        }

        if system_prompt:
            payload["systemInstruction"] = {
                "parts": [{"text": system_prompt}]
            }

        if self.use_vertex:
            url = f"{self.base_url}/{self.model}:generateContent?key={self.api_key}"
            headers = {"Content-Type": "application/json"}
        else:
            url = f"{self.base_url}/models/{self.model}:generateContent"
            headers = {
                "Content-Type": "application/json",
                "x-goog-api-key": self.api_key
            }

        try:
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                log_url = url.split("?key=")[0] if self.use_vertex else url
                logger.info(f"🤖 POST {log_url}")
                response = await client.post(url, json=payload, headers=headers)
                response.raise_for_status()

                result = response.json()

                if "candidates" in result and len(result["candidates"]) > 0:
                    candidate = result["candidates"][0]
                    if "content" in candidate and "parts" in candidate["content"]:
                        parts = candidate["content"]["parts"]
                        if len(parts) > 0 and "text" in parts[0]:
                            generated_text = parts[0]["text"].strip()
                            logger.info(f"✅ Inference successful ({len(generated_text)} chars)")
                            return generated_text

                logger.warning(f"⚠️ Unexpected response format: {result}")
                return "Sorry, I encountered an error processing the response."

        except httpx.TimeoutException as e:
            logger.error(f"⏱️ Inference timeout: {e}")
            raise Exception(f"Inference timeout after 30 seconds: {e}")
        except httpx.HTTPError as e:
            logger.error(f"❌ HTTP error: {e}")
            raise Exception(f"Inference HTTP error: {e}")
        except Exception as e:
            logger.error(f"❌ Inference error: {e}")
            raise Exception(f"Inference failed: {e}")

    async def health_check(self) -> bool:
        """
        Check if Gemini/Vertex API is reachable.
        """
        try:
            if self.use_vertex:
                url = f"{self.base_url}/{self.model}?key={self.api_key}"
                headers = {"Content-Type": "application/json"}
            else:
                url = f"{self.base_url}/models/{self.model}"
                headers = {"x-goog-api-key": self.api_key}

            async with httpx.AsyncClient(timeout=httpx.Timeout(5.0)) as client:
                response = await client.get(url, headers=headers)
                return response.status_code == 200
        except Exception as e:
            logger.warning(f"⚠️ Health check failed: {e}")
            return False
