# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.http_response import AsyncHttpResponse, HttpResponse
from ...core.pagination import AsyncPager, SyncPager
from ...core.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ..errors.bad_request_error import BadRequestError
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.error_response import ErrorResponse
from ..types.http_validation_error import HttpValidationError
from ..types.return_paged_voices import ReturnPagedVoices
from ..types.return_voice import ReturnVoice
from ..types.voice_provider import VoiceProvider

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawVoicesClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def list(
        self,
        *,
        provider: VoiceProvider,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        ascending_order: typing.Optional[bool] = None,
        filter_tag: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[ReturnVoice, ReturnPagedVoices]:
        """
        Lists voices you have saved in your account, or voices from the [Voice Library](https://app.hume.ai/tts/voice-library).

        Parameters
        ----------
        provider : VoiceProvider
            Specify the voice provider to filter voices returned by the endpoint:

            - **`HUME_AI`**: Lists preset, shared voices from Hume's [Voice Library](https://app.hume.ai/tts/voice-library).
            - **`CUSTOM_VOICE`**: Lists custom voices created and saved to your account.

        page_number : typing.Optional[int]
            Specifies the page number to retrieve, enabling pagination.

            This parameter uses zero-based indexing. For example, setting `page_number` to 0 retrieves the first page of results (items 0-9 if `page_size` is 10), setting `page_number` to 1 retrieves the second page (items 10-19), and so on. Defaults to 0, which retrieves the first page.

        page_size : typing.Optional[int]
            Specifies the maximum number of results to include per page, enabling pagination. The value must be between 1 and 100, inclusive.

            For example, if `page_size` is set to 10, each page will include up to 10 items. Defaults to 10.

        ascending_order : typing.Optional[bool]

        filter_tag : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[ReturnVoice, ReturnPagedVoices]
            Success
        """
        page_number = page_number if page_number is not None else 0

        _response = self._client_wrapper.httpx_client.request(
            "v0/tts/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "provider": provider,
                "page_number": page_number,
                "page_size": page_size,
                "ascending_order": ascending_order,
                "filter_tag": filter_tag,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ReturnPagedVoices,
                    parse_obj_as(
                        type_=ReturnPagedVoices,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.voices_page
                _has_next = True
                _get_next = lambda: self.list(
                    provider=provider,
                    page_number=page_number + 1,
                    page_size=page_size,
                    ascending_order=ascending_order,
                    filter_tag=filter_tag,
                    request_options=request_options,
                )
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create(
        self, *, generation_id: str, name: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[ReturnVoice]:
        """
        Saves a new custom voice to your account using the specified TTS generation ID.

        Once saved, this voice can be reused in subsequent TTS requests, ensuring consistent speech style and prosody. For more details on voice creation, see the [Voices Guide](/docs/text-to-speech-tts/voices).

        Parameters
        ----------
        generation_id : str
            A unique ID associated with this TTS generation that can be used as context for generating consistent speech style and prosody across multiple requests.

        name : str
            The name of a **Voice**.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ReturnVoice]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/tts/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "generation_id": generation_id,
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ReturnVoice,
                    parse_obj_as(
                        type_=ReturnVoice,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete(self, *, name: str, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[None]:
        """
        Deletes a previously generated custom voice.

        Parameters
        ----------
        name : str
            Name of the voice to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/tts/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="DELETE",
            params={
                "name": name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawVoicesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        *,
        provider: VoiceProvider,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        ascending_order: typing.Optional[bool] = None,
        filter_tag: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[ReturnVoice, ReturnPagedVoices]:
        """
        Lists voices you have saved in your account, or voices from the [Voice Library](https://app.hume.ai/tts/voice-library).

        Parameters
        ----------
        provider : VoiceProvider
            Specify the voice provider to filter voices returned by the endpoint:

            - **`HUME_AI`**: Lists preset, shared voices from Hume's [Voice Library](https://app.hume.ai/tts/voice-library).
            - **`CUSTOM_VOICE`**: Lists custom voices created and saved to your account.

        page_number : typing.Optional[int]
            Specifies the page number to retrieve, enabling pagination.

            This parameter uses zero-based indexing. For example, setting `page_number` to 0 retrieves the first page of results (items 0-9 if `page_size` is 10), setting `page_number` to 1 retrieves the second page (items 10-19), and so on. Defaults to 0, which retrieves the first page.

        page_size : typing.Optional[int]
            Specifies the maximum number of results to include per page, enabling pagination. The value must be between 1 and 100, inclusive.

            For example, if `page_size` is set to 10, each page will include up to 10 items. Defaults to 10.

        ascending_order : typing.Optional[bool]

        filter_tag : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[ReturnVoice, ReturnPagedVoices]
            Success
        """
        page_number = page_number if page_number is not None else 0

        _response = await self._client_wrapper.httpx_client.request(
            "v0/tts/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="GET",
            params={
                "provider": provider,
                "page_number": page_number,
                "page_size": page_size,
                "ascending_order": ascending_order,
                "filter_tag": filter_tag,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ReturnPagedVoices,
                    parse_obj_as(
                        type_=ReturnPagedVoices,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.voices_page
                _has_next = True

                async def _get_next():
                    return await self.list(
                        provider=provider,
                        page_number=page_number + 1,
                        page_size=page_size,
                        ascending_order=ascending_order,
                        filter_tag=filter_tag,
                        request_options=request_options,
                    )

                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create(
        self, *, generation_id: str, name: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[ReturnVoice]:
        """
        Saves a new custom voice to your account using the specified TTS generation ID.

        Once saved, this voice can be reused in subsequent TTS requests, ensuring consistent speech style and prosody. For more details on voice creation, see the [Voices Guide](/docs/text-to-speech-tts/voices).

        Parameters
        ----------
        generation_id : str
            A unique ID associated with this TTS generation that can be used as context for generating consistent speech style and prosody across multiple requests.

        name : str
            The name of a **Voice**.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ReturnVoice]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/tts/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "generation_id": generation_id,
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ReturnVoice,
                    parse_obj_as(
                        type_=ReturnVoice,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete(
        self, *, name: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Deletes a previously generated custom voice.

        Parameters
        ----------
        name : str
            Name of the voice to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/tts/voices",
            base_url=self._client_wrapper.get_environment().base,
            method="DELETE",
            params={
                "name": name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
