# 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.jsonable_encoder import jsonable_encoder
from ..core.pagination import AsyncPager, SyncPager
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.conflict_error import ConflictError
from ..errors.not_found_error import NotFoundError
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.delete_team_response import DeleteTeamResponse
from ..types.get_team_response import GetTeamResponse
from ..types.http_error import HttpError
from ..types.list_teams_response import ListTeamsResponse
from ..types.team import Team
from .types.apply_team_request_manifest import ApplyTeamRequestManifest
from .types.teams_list_request_type import TeamsListRequestType

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


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

    def list(
        self,
        *,
        limit: typing.Optional[int] = 100,
        offset: typing.Optional[int] = 0,
        type: typing.Optional[TeamsListRequestType] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[Team, ListTeamsResponse]:
        """
        Retrieve all teams associated with the authenticated user. If the user is a tenant admin, returns all teams for the tenant. Pagination is available based on query parameters

        Parameters
        ----------
        limit : typing.Optional[int]
            Number of items per page

        offset : typing.Optional[int]
            Number of items to skip

        type : typing.Optional[TeamsListRequestType]
            Filter teams by type

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

        Returns
        -------
        SyncPager[Team, ListTeamsResponse]
            Returns an array of teams associated with the user or tenant And also the response includes paginated data
        """
        offset = offset if offset is not None else 0

        _response = self._client_wrapper.httpx_client.request(
            "api/svc/v1/teams/user",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "type": type,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListTeamsResponse,
                    parse_obj_as(
                        type_=ListTeamsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = True
                _get_next = lambda: self.list(
                    limit=limit,
                    offset=offset + len(_items),
                    type=type,
                    request_options=request_options,
                )
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            _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_or_update(
        self,
        *,
        manifest: ApplyTeamRequestManifest,
        dry_run: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[GetTeamResponse]:
        """
        Creates a new team or updates an existing team. It ensures that the team name is unique, valid, and that the team has at least one member. The members of the team are added or updated based on the provided emails.

        Parameters
        ----------
        manifest : ApplyTeamRequestManifest
            Team manifest

        dry_run : typing.Optional[bool]
            Dry run

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

        Returns
        -------
        HttpResponse[GetTeamResponse]
            Returns the created or updated team.
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/svc/v1/teams",
            method="PUT",
            json={
                "manifest": convert_and_respect_annotation_metadata(
                    object_=manifest, annotation=ApplyTeamRequestManifest, direction="write"
                ),
                "dryRun": dry_run,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetTeamResponse,
                    parse_obj_as(
                        type_=GetTeamResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpError,
                        parse_obj_as(
                            type_=HttpError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[GetTeamResponse]:
        """
        Get Team associated with provided team id

        Parameters
        ----------
        id : str
            Team Id

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

        Returns
        -------
        HttpResponse[GetTeamResponse]
            Returns the Team associated with provided team id
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/svc/v1/teams/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetTeamResponse,
                    parse_obj_as(
                        type_=GetTeamResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteTeamResponse]:
        """
        Deletes the Team associated with the provided Id.

        Parameters
        ----------
        id : str
            Team Id

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

        Returns
        -------
        HttpResponse[DeleteTeamResponse]
            Successfully deleted the team.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/svc/v1/teams/{jsonable_encoder(id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteTeamResponse,
                    parse_obj_as(
                        type_=DeleteTeamResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpError,
                        parse_obj_as(
                            type_=HttpError,  # 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 AsyncRawTeamsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        *,
        limit: typing.Optional[int] = 100,
        offset: typing.Optional[int] = 0,
        type: typing.Optional[TeamsListRequestType] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[Team, ListTeamsResponse]:
        """
        Retrieve all teams associated with the authenticated user. If the user is a tenant admin, returns all teams for the tenant. Pagination is available based on query parameters

        Parameters
        ----------
        limit : typing.Optional[int]
            Number of items per page

        offset : typing.Optional[int]
            Number of items to skip

        type : typing.Optional[TeamsListRequestType]
            Filter teams by type

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

        Returns
        -------
        AsyncPager[Team, ListTeamsResponse]
            Returns an array of teams associated with the user or tenant And also the response includes paginated data
        """
        offset = offset if offset is not None else 0

        _response = await self._client_wrapper.httpx_client.request(
            "api/svc/v1/teams/user",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "type": type,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListTeamsResponse,
                    parse_obj_as(
                        type_=ListTeamsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.data
                _has_next = True

                async def _get_next():
                    return await self.list(
                        limit=limit,
                        offset=offset + len(_items),
                        type=type,
                        request_options=request_options,
                    )

                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            _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_or_update(
        self,
        *,
        manifest: ApplyTeamRequestManifest,
        dry_run: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[GetTeamResponse]:
        """
        Creates a new team or updates an existing team. It ensures that the team name is unique, valid, and that the team has at least one member. The members of the team are added or updated based on the provided emails.

        Parameters
        ----------
        manifest : ApplyTeamRequestManifest
            Team manifest

        dry_run : typing.Optional[bool]
            Dry run

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

        Returns
        -------
        AsyncHttpResponse[GetTeamResponse]
            Returns the created or updated team.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/svc/v1/teams",
            method="PUT",
            json={
                "manifest": convert_and_respect_annotation_metadata(
                    object_=manifest, annotation=ApplyTeamRequestManifest, direction="write"
                ),
                "dryRun": dry_run,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetTeamResponse,
                    parse_obj_as(
                        type_=GetTeamResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpError,
                        parse_obj_as(
                            type_=HttpError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetTeamResponse]:
        """
        Get Team associated with provided team id

        Parameters
        ----------
        id : str
            Team Id

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

        Returns
        -------
        AsyncHttpResponse[GetTeamResponse]
            Returns the Team associated with provided team id
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/svc/v1/teams/{jsonable_encoder(id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetTeamResponse,
                    parse_obj_as(
                        type_=GetTeamResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteTeamResponse]:
        """
        Deletes the Team associated with the provided Id.

        Parameters
        ----------
        id : str
            Team Id

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

        Returns
        -------
        AsyncHttpResponse[DeleteTeamResponse]
            Successfully deleted the team.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/svc/v1/teams/{jsonable_encoder(id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteTeamResponse,
                    parse_obj_as(
                        type_=DeleteTeamResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpError,
                        parse_obj_as(
                            type_=HttpError,  # 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)
