"""
Gemini Provider - Phase 24 ADR-052
====================================
Google Gemini Cloud API (gemini-2.0-flash)

搬移自: openclaw.py _call_gemini (L411-472)
特性: 穩定快速、JSON 輸出可靠、有費用 ($0.075/1M input)

2026-04-02 ogt: Phase 24-A 從 openclaw.py 抽出
"""

from __future__ import annotations

import time

import httpx
import structlog

from src.core.config import get_settings
from src.services.ai_providers.interfaces import AIProvider, AIResult, is_provider_enabled_by_env
from src.services.model_registry import get_model_registry

logger = structlog.get_logger(__name__)
settings = get_settings()


class GeminiProvider:
    """
    Google Gemini Cloud Provider

    privacy_level: cloud (禁止機密資料)
    capabilities: rca, chat
    """

    def __init__(self) -> None:
        self._http_client: httpx.AsyncClient | None = None

    async def _get_client(self) -> httpx.AsyncClient:
        if self._http_client is None or self._http_client.is_closed:
            self._http_client = httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0))
        return self._http_client

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

    @property
    def is_enabled(self) -> bool:
        if not settings.GEMINI_API_KEY:
            return False
        return is_provider_enabled_by_env("gemini")

    @property
    def capabilities(self) -> set[str]:
        return {"rca", "chat"}

    @property
    def privacy_level(self) -> str:
        return "cloud"

    async def analyze(
        self,
        prompt: str,
        context: dict | None = None,
    ) -> AIResult:
        if not settings.GEMINI_API_KEY:
            return AIResult(raw_response="", success=False, provider=self.name, error="GEMINI_API_KEY not configured")

        start = time.perf_counter()
        try:
            client = await self._get_client()
            registry = get_model_registry()
            model_name = registry.get_model("gemini", "rca")

            response = await client.post(
                f"https://generativelanguage.googleapis.com/v1beta/models/{model_name}:generateContent?key={settings.GEMINI_API_KEY}",
                json={
                    "contents": [{"parts": [{"text": prompt}]}],
                    "generationConfig": {
                        "temperature": registry.get_provider_options("gemini").get("temperature", 0.1),
                        "maxOutputTokens": 2048,
                        "responseMimeType": "application/json",
                    },
                },
                timeout=30.0,
            )
            response.raise_for_status()
            data = response.json()
            text = data["candidates"][0]["content"]["parts"][0]["text"]

            # Token/Cost 追蹤
            usage = data.get("usageMetadata", {})
            prompt_tokens = usage.get("promptTokenCount", 0)
            completion_tokens = usage.get("candidatesTokenCount", 0)
            total_tokens = usage.get("totalTokenCount", prompt_tokens + completion_tokens)
            # Gemini 1.5 Flash: Input $0.075/1M, Output $0.30/1M
            cost_usd = (prompt_tokens * 0.000000075) + (completion_tokens * 0.0000003)
            latency = (time.perf_counter() - start) * 1000

            logger.info(
                "gemini_provider_success",
                response_length=len(text),
                total_tokens=total_tokens,
                cost_usd=f"${cost_usd:.6f}",
                latency_ms=round(latency, 1),
            )
            return AIResult(
                raw_response=text,
                success=True,
                provider=self.name,
                tokens=total_tokens,
                cost_usd=cost_usd,
                latency_ms=latency,
            )

        except Exception as e:
            latency = (time.perf_counter() - start) * 1000
            logger.warning("gemini_provider_failed", error=str(e), latency_ms=round(latency, 1))
            return AIResult(raw_response="", success=False, provider=self.name, latency_ms=latency, error=str(e))

    async def health_check(self) -> bool:
        return bool(settings.GEMINI_API_KEY)

    async def close(self) -> None:
        if self._http_client:
            await self._http_client.aclose()
            self._http_client = None
