"""
Perplexity Responses API — OpenAI-compatible.

The only provider quirks:
- cost returned as dict → handled by ResponseAPIUsage.parse_cost validator
- preset models (preset/pro-search) → handled by transform_responses_api_request
- HTTP 200 with status:"failed" → raised as exception in transform_response_api_response

Ref: https://docs.perplexity.ai/api-reference/responses-post
"""

from typing import Any, Dict, List, Optional, Union

import httpx

from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
from litellm.llms.base_llm.chat.transformation import BaseLLMException
from litellm.llms.openai.responses.transformation import OpenAIResponsesAPIConfig
from litellm.secret_managers.main import get_secret_str
from litellm.types.llms.openai import ResponseInputParam, ResponsesAPIResponse
from litellm.types.router import GenericLiteLLMParams
from litellm.types.utils import LlmProviders


class PerplexityResponsesConfig(OpenAIResponsesAPIConfig):
    def get_supported_openai_params(self, model: str) -> list:
        """Ref: https://docs.perplexity.ai/api-reference/responses-post"""
        return [
            "max_output_tokens",
            "stream",
            "temperature",
            "top_p",
            "tools",
            "reasoning",
            "instructions",
            "models",
        ]

    @property
    def custom_llm_provider(self) -> LlmProviders:
        return LlmProviders.PERPLEXITY

    def validate_environment(
        self, headers: dict, model: str, litellm_params: Optional[GenericLiteLLMParams]
    ) -> dict:
        litellm_params = litellm_params or GenericLiteLLMParams()
        api_key = (
            litellm_params.api_key
            or get_secret_str("PERPLEXITYAI_API_KEY")
            or get_secret_str("PERPLEXITY_API_KEY")
        )
        if api_key:
            headers["Authorization"] = f"Bearer {api_key}"
        return headers

    def get_complete_url(self, api_base: Optional[str], litellm_params: dict) -> str:
        api_base = (
            api_base
            or get_secret_str("PERPLEXITY_API_BASE")
            or "https://api.perplexity.ai"
        )
        return f"{api_base.rstrip('/')}/v1/responses"

    def _ensure_message_type(
        self, input: Union[str, ResponseInputParam]
    ) -> Union[str, ResponseInputParam]:
        """Ensure list input items have type='message' (required by Perplexity)."""
        if isinstance(input, str):
            return input
        if isinstance(input, list):
            result: List[Any] = []
            for item in input:
                if isinstance(item, dict) and "type" not in item:
                    new_item = dict(
                        item
                    )  # convert to plain dict to avoid TypedDict checking
                    new_item["type"] = "message"
                    result.append(new_item)
                else:
                    result.append(item)
            return result
        return input

    def transform_responses_api_request(
        self,
        model: str,
        input: Union[str, ResponseInputParam],
        response_api_optional_request_params: Dict,
        litellm_params: GenericLiteLLMParams,
        headers: dict,
    ) -> Dict:
        """Handle preset/ model prefix: send as {"preset": name} instead of {"model": name}."""
        input = self._ensure_message_type(input)
        if model.startswith("preset/"):
            input = self._validate_input_param(input)
            data: Dict = {
                "preset": model[len("preset/") :],
                "input": input,
            }
            data.update(response_api_optional_request_params)
            return data
        return super().transform_responses_api_request(
            model=model,
            input=input,
            response_api_optional_request_params=response_api_optional_request_params,
            litellm_params=litellm_params,
            headers=headers,
        )

    def transform_response_api_response(
        self,
        model: str,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,
    ) -> ResponsesAPIResponse:
        """Check for Perplexity's status:'failed' on HTTP 200 before delegating to base."""
        try:
            raw_response_json = raw_response.json()
        except Exception:
            raw_response_json = None

        if (
            isinstance(raw_response_json, dict)
            and raw_response_json.get("status") == "failed"
        ):
            error = raw_response_json.get("error", {})
            raise BaseLLMException(
                status_code=raw_response.status_code,
                message=error.get("message", "Unknown Perplexity error"),
            )

        return super().transform_response_api_response(
            model=model,
            raw_response=raw_response,
            logging_obj=logging_obj,
        )

    def supports_native_websocket(self) -> bool:
        """Perplexity does not support native WebSocket for Responses API"""
        return False
