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

import typing
from json.decoder import JSONDecodeError

from .... import core
from ....core.api_error import ApiError
from ....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ....core.http_response import AsyncHttpResponse, HttpResponse
from ....core.jsonable_encoder import jsonable_encoder
from ....core.parse_error import ParsingError
from ....core.request_options import RequestOptions
from ....core.unchecked_base_model import construct_type
from ....errors.unprocessable_entity_error import UnprocessableEntityError
from ....types.add_voice_response_model import AddVoiceResponseModel
from ....types.delete_voice_sample_response_model import DeleteVoiceSampleResponseModel
from ....types.voice_sample import VoiceSample
from pydantic import ValidationError

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


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

    def create(
        self,
        voice_id: str,
        *,
        files: typing.List[core.File],
        remove_background_noise: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.List[VoiceSample]]:
        """
        Add audio samples to a PVC voice

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

        files : typing.List[core.File]
            See core.File for more documentation

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

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

        Returns
        -------
        HttpResponse[typing.List[VoiceSample]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/pvc/{jsonable_encoder(voice_id)}/samples",
            method="POST",
            data={
                "remove_background_noise": remove_background_noise,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[VoiceSample],
                    construct_type(
                        type_=typing.List[VoiceSample],  # 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(
                        typing.Any,
                        construct_type(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update(
        self,
        voice_id: str,
        sample_id: str,
        *,
        remove_background_noise: typing.Optional[bool] = OMIT,
        selected_speaker_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        trim_start_time: typing.Optional[int] = OMIT,
        trim_end_time: typing.Optional[int] = OMIT,
        file_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AddVoiceResponseModel]:
        """
        Update a PVC voice sample - apply noise removal, select speaker, change trim times or file name.

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

        sample_id : str
            Sample ID to be used

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

        selected_speaker_ids : typing.Optional[typing.Sequence[str]]
            Speaker IDs to be used for PVC training. Make sure you send all the speaker IDs you want to use for PVC training in one request because the last request will override the previous ones.

        trim_start_time : typing.Optional[int]
            The start time of the audio to be used for PVC training. Time should be in milliseconds

        trim_end_time : typing.Optional[int]
            The end time of the audio to be used for PVC training. Time should be in milliseconds

        file_name : typing.Optional[str]
            The name of the audio file to be used for PVC training.

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

        Returns
        -------
        HttpResponse[AddVoiceResponseModel]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/pvc/{jsonable_encoder(voice_id)}/samples/{jsonable_encoder(sample_id)}",
            method="POST",
            json={
                "remove_background_noise": remove_background_noise,
                "selected_speaker_ids": selected_speaker_ids,
                "trim_start_time": trim_start_time,
                "trim_end_time": trim_end_time,
                "file_name": file_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AddVoiceResponseModel,
                    construct_type(
                        type_=AddVoiceResponseModel,  # 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(
                        typing.Any,
                        construct_type(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete(
        self, voice_id: str, sample_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteVoiceSampleResponseModel]:
        """
        Delete a sample from a PVC voice.

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

        sample_id : str
            Sample ID to be used

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

        Returns
        -------
        HttpResponse[DeleteVoiceSampleResponseModel]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/voices/pvc/{jsonable_encoder(voice_id)}/samples/{jsonable_encoder(sample_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteVoiceSampleResponseModel,
                    construct_type(
                        type_=DeleteVoiceSampleResponseModel,  # 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(
                        typing.Any,
                        construct_type(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def create(
        self,
        voice_id: str,
        *,
        files: typing.List[core.File],
        remove_background_noise: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.List[VoiceSample]]:
        """
        Add audio samples to a PVC voice

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

        files : typing.List[core.File]
            See core.File for more documentation

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

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

        Returns
        -------
        AsyncHttpResponse[typing.List[VoiceSample]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/pvc/{jsonable_encoder(voice_id)}/samples",
            method="POST",
            data={
                "remove_background_noise": remove_background_noise,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[VoiceSample],
                    construct_type(
                        type_=typing.List[VoiceSample],  # 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(
                        typing.Any,
                        construct_type(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update(
        self,
        voice_id: str,
        sample_id: str,
        *,
        remove_background_noise: typing.Optional[bool] = OMIT,
        selected_speaker_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        trim_start_time: typing.Optional[int] = OMIT,
        trim_end_time: typing.Optional[int] = OMIT,
        file_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AddVoiceResponseModel]:
        """
        Update a PVC voice sample - apply noise removal, select speaker, change trim times or file name.

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

        sample_id : str
            Sample ID to be used

        remove_background_noise : typing.Optional[bool]
            If set will remove background noise for voice samples using our audio isolation model. If the samples do not include background noise, it can make the quality worse.

        selected_speaker_ids : typing.Optional[typing.Sequence[str]]
            Speaker IDs to be used for PVC training. Make sure you send all the speaker IDs you want to use for PVC training in one request because the last request will override the previous ones.

        trim_start_time : typing.Optional[int]
            The start time of the audio to be used for PVC training. Time should be in milliseconds

        trim_end_time : typing.Optional[int]
            The end time of the audio to be used for PVC training. Time should be in milliseconds

        file_name : typing.Optional[str]
            The name of the audio file to be used for PVC training.

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

        Returns
        -------
        AsyncHttpResponse[AddVoiceResponseModel]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/pvc/{jsonable_encoder(voice_id)}/samples/{jsonable_encoder(sample_id)}",
            method="POST",
            json={
                "remove_background_noise": remove_background_noise,
                "selected_speaker_ids": selected_speaker_ids,
                "trim_start_time": trim_start_time,
                "trim_end_time": trim_end_time,
                "file_name": file_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AddVoiceResponseModel,
                    construct_type(
                        type_=AddVoiceResponseModel,  # 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(
                        typing.Any,
                        construct_type(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete(
        self, voice_id: str, sample_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteVoiceSampleResponseModel]:
        """
        Delete a sample from a PVC voice.

        Parameters
        ----------
        voice_id : str
            Voice ID to be used, you can use https://api.elevenlabs.io/v1/voices to list all the available voices.

        sample_id : str
            Sample ID to be used

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

        Returns
        -------
        AsyncHttpResponse[DeleteVoiceSampleResponseModel]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/voices/pvc/{jsonable_encoder(voice_id)}/samples/{jsonable_encoder(sample_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteVoiceSampleResponseModel,
                    construct_type(
                        type_=DeleteVoiceSampleResponseModel,  # 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(
                        typing.Any,
                        construct_type(
                            type_=typing.Any,  # 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)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
