"""AI integration pattern with semaphore limiting and caching.

This service demonstrates how to integrate OpenAI or similar LLM APIs
in a healthcare context with concurrency control and response caching.
"""
import asyncio
import hashlib
import json
import logging

import httpx

from app.config import settings
from app.services.cache_service import CacheService

logger = logging.getLogger(__name__)

# Limit concurrent AI API calls to avoid rate limits and runaway costs
_semaphore = asyncio.Semaphore(settings.ai_max_concurrent)


class AIService:
    """Generate AI-powered explanations for drug interactions."""

    def __init__(self, cache: CacheService | None = None):
        self.cache = cache
        self.api_key = settings.openai_api_key
        self.model = settings.ai_model

    def _cache_key(self, prompt: str) -> str:
        digest = hashlib.sha256(prompt.encode()).hexdigest()[:16]
        return f"ai:explanation:{digest}"

    async def explain_interaction(
        self,
        drug_a: str,
        drug_b: str,
        severity: str,
    ) -> str:
        """Get an AI-generated plain-language explanation for an interaction.

        Returns a cached response if available, otherwise calls the AI API
        with concurrency limiting via semaphore.
        """
        prompt = (
            f"Explain the drug interaction between {drug_a} and {drug_b} "
            f"(severity: {severity}) in simple language a patient can understand. "
            f"Keep it under 150 words. Include what to watch for and when to "
            f"contact a healthcare provider."
        )

        # Check cache first
        if self.cache:
            cached = await self.cache.get(self._cache_key(prompt))
            if cached:
                return cached

        if not self.api_key:
            return "AI explanation unavailable. Please consult your pharmacist."

        async with _semaphore:
            try:
                async with httpx.AsyncClient(timeout=30.0) as client:
                    response = await client.post(
                        "https://api.openai.com/v1/chat/completions",
                        headers={
                            "Authorization": f"Bearer {self.api_key}",
                            "Content-Type": "application/json",
                        },
                        json={
                            "model": self.model,
                            "messages": [
                                {
                                    "role": "system",
                                    "content": (
                                        "You are a pharmacist assistant. Provide clear, "
                                        "accurate drug interaction information. Always "
                                        "recommend consulting a healthcare professional."
                                    ),
                                },
                                {"role": "user", "content": prompt},
                            ],
                            "max_tokens": 300,
                            "temperature": 0.3,
                        },
                    )
                    response.raise_for_status()
                    data = response.json()
                    explanation = data["choices"][0]["message"]["content"]

                # Cache the result
                if self.cache:
                    await self.cache.set(
                        self._cache_key(prompt), explanation, ttl_category="ai"
                    )

                return explanation

            except Exception:
                logger.exception("AI service call failed")
                return "AI explanation temporarily unavailable. Please consult your pharmacist."
