from __future__ import annotations

import base64
import logging
import time
from typing import Any

import httpx

from app.core.ai.domain.models import (
    AiModelSpec,
    AiProviderType,
    AiResponse,
    AiTextRequest,
    AiVisionRequest,
)

logger = logging.getLogger("dscons.ai.adapter.openrouter")


class OpenRouterAdapter:
    """High-Availability Cloud Adapter for OpenRouter endpoints."""

    def __init__(
        self,
        api_key: str,
        base_url: str = "https://openrouter.ai/api/v1",
        timeout_seconds: float = 35.0,
    ) -> None:
        self._api_key = api_key
        self._base_url = base_url.rstrip("/")
        self._timeout = timeout_seconds

    async def generate_text(
        self, request: AiTextRequest, spec: AiModelSpec
    ) -> AiResponse:
        """Executes text generation through OpenRouter."""
        t0 = time.perf_counter()
        messages: list[dict[str, Any]] = []

        if request.system_prompt:
            messages.append({"role": "system", "content": request.system_prompt})

        if request.messages:
            messages.extend(request.messages)
        elif request.prompt:
            messages.append({"role": "user", "content": request.prompt})

        payload = {
            "model": spec.provider_model_id,
            "messages": messages,
            "temperature": request.temperature,
            "max_tokens": request.max_tokens or spec.max_output_tokens,
        }
        if request.extra_body:
            payload.update(request.extra_body)

        headers = {
            "Authorization": f"Bearer {self._api_key}",
            "Content-Type": "application/json",
            "HTTP-Referer": "https://dscons.vn",
            "X-Title": "DSCons ERP AI Gateway",
        }

        async with httpx.AsyncClient(timeout=self._timeout) as client:
            res = await client.post(
                f"{self._base_url}/chat/completions", json=payload, headers=headers
            )
            res.raise_for_status()
            data = res.json()

        choice = data["choices"][0]
        content = choice.get("message", {}).get("content") or ""
        if not content:
            raise ValueError(f"Empty text completion received from OpenRouter ({spec.provider_model_id}).")
        usage = data.get("usage", {})

        latency = (time.perf_counter() - t0) * 1000.0
        return AiResponse(
            content=content,
            model_used=spec.canonical_id,
            provider_used=AiProviderType.OPENROUTER,
            latency_ms=latency,
            prompt_tokens=usage.get("prompt_tokens", 0),
            completion_tokens=usage.get("completion_tokens", 0),
        )

    async def analyze_vision(
        self, request: AiVisionRequest, spec: AiModelSpec
    ) -> AiResponse:
        """Executes multimodal vision inference through OpenRouter."""
        t0 = time.perf_counter()
        data_uri = request.data_uri

        if not data_uri and request.image_bytes:
            b64 = base64.b64encode(request.image_bytes).decode("ascii")
            data_uri = f"data:{request.image_mime};base64,{b64}"

        if not data_uri:
            raise ValueError("No image payload or data_uri provided for vision.")

        payload = {
            "model": spec.provider_model_id,
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {"type": "text", "text": request.prompt},
                        {"type": "image_url", "image_url": {"url": data_uri}},
                    ],
                }
            ],
            "temperature": request.temperature,
            "max_tokens": max(request.max_tokens, 300),
        }

        headers = {
            "Authorization": f"Bearer {self._api_key}",
            "Content-Type": "application/json",
            "HTTP-Referer": "https://dscons.vn",
            "X-Title": "DSCons ERP AI Gateway",
        }

        async with httpx.AsyncClient(timeout=self._timeout) as client:
            res = await client.post(
                f"{self._base_url}/chat/completions", json=payload, headers=headers
            )
            res.raise_for_status()
            data = res.json()

        choice = data["choices"][0]
        msg = choice.get("message", {})
        content = msg.get("content") or msg.get("reasoning") or ""
        if not content:
            raise ValueError(f"Empty vision completion received from OpenRouter ({spec.provider_model_id}).")
        usage = data.get("usage", {})

        latency = (time.perf_counter() - t0) * 1000.0
        return AiResponse(
            content=content,
            model_used=spec.canonical_id,
            provider_used=AiProviderType.OPENROUTER,
            latency_ms=latency,
            prompt_tokens=usage.get("prompt_tokens", 0),
            completion_tokens=usage.get("completion_tokens", 0),
        )
