"""ElevenLabs TextToSpeech API parameter mappers."""

from typing import Any

from celeste.artifacts import AudioArtifact
from celeste.models import Model
from celeste.parameters import FieldMapper, ParameterMapper
from celeste.types import AudioContent


class VoiceMapper(FieldMapper[AudioContent]):
    """Map voice parameter to ElevenLabs URL path.

    Note: Voice ID goes in URL path, not request body.
    This mapper validates the voice_id but the actual URL construction
    happens in _make_request().
    """

    field = "_voice_id"


class OutputFormatMapper(ParameterMapper[AudioContent]):
    """Map response_format parameter to ElevenLabs output_format field."""

    def map(
        self,
        request: dict[str, Any],
        value: object,
        model: Model,
    ) -> dict[str, Any]:
        """Transform response_format into provider request."""
        validated_value = self._validate_value(value, model)
        if validated_value is None:
            request["output_format"] = "mp3_44100_128"
            return request

        request["output_format"] = validated_value
        return request

    def parse_output(self, content: AudioContent, value: object | None) -> AudioContent:
        """Apply output_format → MIME type mapping to parsed content."""
        if not isinstance(content, AudioArtifact):
            return content

        # Lazy import to avoid circular dependency
        from celeste.providers.elevenlabs.text_to_speech.client import (
            ElevenLabsTextToSpeechClient,
        )

        mime_type = ElevenLabsTextToSpeechClient._map_output_format_to_mime_type(
            str(value) if value else None
        )
        return AudioArtifact(data=content.data, mime_type=mime_type)


class SpeedMapper(ParameterMapper[AudioContent]):
    """Map speed parameter to ElevenLabs voice_settings.speed field."""

    def map(
        self,
        request: dict[str, Any],
        value: object,
        model: Model,
    ) -> dict[str, Any]:
        """Transform speed into provider request."""
        validated_value = self._validate_value(value, model)
        if validated_value is None:
            return request

        if "voice_settings" not in request:
            request["voice_settings"] = {}

        request["voice_settings"]["speed"] = validated_value
        return request


class LanguageCodeMapper(ParameterMapper[AudioContent]):
    """Map language parameter to ElevenLabs language_code field.

    Only supported by eleven_turbo_v2_5 and eleven_flash_v2_5 models.
    """

    def map(
        self,
        request: dict[str, Any],
        value: object,
        model: Model,
    ) -> dict[str, Any]:
        """Transform language into provider request."""
        validated_value = self._validate_value(value, model)
        if validated_value is None:
            return request

        request["language_code"] = str(validated_value)
        return request


__all__ = [
    "LanguageCodeMapper",
    "OutputFormatMapper",
    "SpeedMapper",
    "VoiceMapper",
]
