"""
Gemini AI Provider implementation
"""
import logging
import subprocess
import shutil
import requests
import time
from typing import Dict, Any, Optional

from ..config import settings
from ..core import AIProcessingError
from .base_provider import AIProvider


class GeminiProvider(AIProvider):
    """Gemini AI provider using CLI or API"""

    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self._cli_path = settings.GEMINI_CLI_PATH or shutil.which("gemini")
        self._api_key = settings.GEMINI_API_KEY
        self._flash_model = settings.GEMINI_FLASH_MODEL
        self._pro_model = settings.GEMINI_PRO_MODEL
        self._session = None

    @property
    def name(self) -> str:
        return "Gemini"

    def is_available(self) -> bool:
        """Check if Gemini is available"""
        return bool(self._cli_path or self._api_key)

    def _run_cli(self, prompt: str, use_flash: bool = True, timeout: int = 300) -> str:
        """Run Gemini CLI with prompt"""
        if not self._cli_path:
            raise AIProcessingError("Gemini CLI not available")

        model = self._flash_model if use_flash else self._pro_model
        cmd = [self._cli_path, model, prompt]

        try:
            process = subprocess.run(
                cmd,
                text=True,
                capture_output=True,
                timeout=timeout,
                shell=False
            )

            if process.returncode != 0:
                error_msg = process.stderr or "Unknown error"
                raise AIProcessingError(f"Gemini CLI failed: {error_msg}")

            return process.stdout.strip()
        except subprocess.TimeoutExpired:
            raise AIProcessingError(f"Gemini CLI timed out after {timeout}s")
        except Exception as e:
            raise AIProcessingError(f"Gemini CLI error: {e}")

    def _call_api(self, prompt: str, use_flash: bool = True, timeout: int = 180) -> str:
        """Call Gemini API"""
        if not self._api_key:
            raise AIProcessingError("Gemini API key not configured")

        model = self._flash_model if use_flash else self._pro_model

        # Initialize session if needed
        if self._session is None:
            self._session = requests.Session()
            adapter = requests.adapters.HTTPAdapter(
                pool_connections=10,
                pool_maxsize=20
            )
            self._session.mount('https://', adapter)

        url = f"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent"

        payload = {
            "contents": [{
                "parts": [{"text": prompt}]
            }]
        }

        params = {"key": self._api_key}

        try:
            response = self._session.post(
                url,
                json=payload,
                params=params,
                timeout=timeout
            )
            response.raise_for_status()

            data = response.json()

            if "candidates" not in data or not data["candidates"]:
                raise AIProcessingError("Empty response from Gemini API")

            candidate = data["candidates"][0]
            if "content" not in candidate or "parts" not in candidate["content"]:
                raise AIProcessingError("Invalid response format from Gemini API")

            result = candidate["content"]["parts"][0]["text"]
            return result.strip()

        except requests.RequestException as e:
            raise AIProcessingError(f"Gemini API request failed: {e}")
        except (KeyError, IndexError, ValueError) as e:
            raise AIProcessingError(f"Gemini API response error: {e}")

    def _run(self, prompt: str, use_flash: bool = True, timeout: int = 300) -> str:
        """Run Gemini with fallback between CLI and API"""
        # Try CLI first if available
        if self._cli_path:
            try:
                return self._run_cli(prompt, use_flash, timeout)
            except Exception as e:
                self.logger.warning(f"Gemini CLI failed, trying API: {e}")

        # Fallback to API
        if self._api_key:
            api_timeout = timeout if timeout < 180 else 180
            return self._call_api(prompt, use_flash, api_timeout)

        raise AIProcessingError("No Gemini provider available (CLI or API)")

    def summarize(self, text: str, **kwargs) -> str:
        """Generate summary using Gemini"""
        prompt = f"""Summarize the following text:

{text}

Provide a clear, concise summary in Spanish."""
        return self._run(prompt, use_flash=True)

    def correct_text(self, text: str, **kwargs) -> str:
        """Correct text using Gemini"""
        prompt = f"""Correct the following text for grammar, spelling, and clarity:

{text}

Return only the corrected text, nothing else."""
        return self._run(prompt, use_flash=True)

    def classify_content(self, text: str, **kwargs) -> Dict[str, Any]:
        """Classify content using Gemini"""
        categories = ["historia", "analisis_contable", "instituciones_gobierno", "otras_clases"]

        prompt = f"""Classify the following text into one of these categories:
- historia
- analisis_contable
- instituciones_gobierno
- otras_clases

Text: {text}

Return only the category name, nothing else."""
        result = self._run(prompt, use_flash=True).lower()

        # Validate result
        if result not in categories:
            result = "otras_clases"

        return {
            "category": result,
            "confidence": 0.9,
            "provider": self.name
        }
