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

import typing
from json.decoder import JSONDecodeError

from ..commons.errors.bad_request_error import BadRequestError
from ..commons.errors.not_found_error import NotFoundError
from ..commons.errors.server_error import ServerError
from ..commons.types.error_message import ErrorMessage
from ..conversation.types.conversation_filter import ConversationFilter
from ..conversation.types.feedback_filter import FeedbackFilter
from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..users.types.agent_user_filter import AgentUserFilter
from .types.agent_user_column_definition import AgentUserColumnDefinition
from .types.agent_user_table_response import AgentUserTableResponse
from .types.chart_response import ChartResponse
from .types.conversation_chart_request import ConversationChartRequest
from .types.conversation_column_definition import ConversationColumnDefinition
from .types.conversation_group_by import ConversationGroupBy
from .types.conversation_table_response import ConversationTableResponse
from .types.feedback_column_definition import FeedbackColumnDefinition
from .types.feedback_group_by import FeedbackGroupBy
from .types.feedback_table_response import FeedbackTableResponse
from .types.time_interval import TimeInterval

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


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

    def get_conversation_table(
        self,
        *,
        field_groupings: typing.Sequence[ConversationGroupBy],
        column_definitions: typing.Sequence[ConversationColumnDefinition],
        time_grouping: typing.Optional[TimeInterval] = OMIT,
        conversation_filter: typing.Optional[ConversationFilter] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ConversationTableResponse]:
        """
        Retrieves structured conversation data formatted as a table, allowing users to group, filter, and define specific metrics to display as columns.

        Parameters
        ----------
        field_groupings : typing.Sequence[ConversationGroupBy]
            Specifies the fields by which data should be grouped. Each unique combination forms a row.
            If multiple fields are provided, the result is grouped by their unique value combinations.
            If empty, all data is aggregated into a single row. |
            Note: The field `CreatedAt` should not be used here, all time-based grouping should be done using the `timeGrouping` field.

        column_definitions : typing.Sequence[ConversationColumnDefinition]
            Specifies the metrics to be displayed as columns. Column headers act as keys, with computed metric values as their mapped values. There needs to be at least one column definition in the table request.

        time_grouping : typing.Optional[TimeInterval]
            Defines the time interval for grouping data. If specified, data is grouped accordingly  based on the time they were created. Example: If set to "DAY," data will be aggregated by day.

        conversation_filter : typing.Optional[ConversationFilter]
            Optional filter applied to refine the conversation data before processing.

        timezone : typing.Optional[str]
            IANA timezone identifier (e.g., "America/Los_Angeles").
            When provided, time-based groupings (e.g., DAY) and date filters are evaluated in this timezone;
            otherwise UTC is used.

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

        Returns
        -------
        HttpResponse[ConversationTableResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/tables/conversations",
            method="POST",
            json={
                "timeGrouping": time_grouping,
                "fieldGroupings": convert_and_respect_annotation_metadata(
                    object_=field_groupings, annotation=typing.Sequence[ConversationGroupBy], direction="write"
                ),
                "columnDefinitions": convert_and_respect_annotation_metadata(
                    object_=column_definitions,
                    annotation=typing.Sequence[ConversationColumnDefinition],
                    direction="write",
                ),
                "conversationFilter": convert_and_respect_annotation_metadata(
                    object_=conversation_filter, annotation=ConversationFilter, direction="write"
                ),
                "timezone": timezone,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConversationTableResponse,
                    parse_obj_as(
                        type_=ConversationTableResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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_conversation_chart(
        self, *, request: ConversationChartRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[ChartResponse]:
        """
        Fetches conversation data visualized in a chart format. Supported chart types include pie chart, date histogram, and stacked bar charts.

        Parameters
        ----------
        request : ConversationChartRequest

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

        Returns
        -------
        HttpResponse[ChartResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/charts/conversations",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=ConversationChartRequest, direction="write"
            ),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ChartResponse,
                    parse_obj_as(
                        type_=ChartResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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_feedback_table(
        self,
        *,
        field_groupings: typing.Sequence[FeedbackGroupBy],
        column_definitions: typing.Sequence[FeedbackColumnDefinition],
        time_grouping: typing.Optional[TimeInterval] = OMIT,
        feedback_filter: typing.Optional[FeedbackFilter] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[FeedbackTableResponse]:
        """
        Retrieves structured feedback data formatted as a table, allowing users to group, filter,  and define specific metrics to display as columns.

        Parameters
        ----------
        field_groupings : typing.Sequence[FeedbackGroupBy]
            Specifies the fields by which data should be grouped. Each unique combination forms a row.
            If multiple fields are provided, the result is grouped by their unique value combinations.
            If empty, all data is aggregated into a single row.
            Note: The field CreatedAt should not be used here, all the time-based grouping should be done using the timeGrouping field.

        column_definitions : typing.Sequence[FeedbackColumnDefinition]
            Specifies the metrics to be displayed as columns.
            Column headers act as keys, with computed metric values as their mapped values.
            There needs to be at least one column definition in the table request.

        time_grouping : typing.Optional[TimeInterval]
            Defines the time interval for grouping data. If specified, data is grouped accordingly based on the time they were created.
             Example: If set to "DAY," data will be aggregated by day.

        feedback_filter : typing.Optional[FeedbackFilter]
            Optional filter applied to refine the feedback data before processing.

        timezone : typing.Optional[str]
            IANA timezone identifier (e.g., "America/Los_Angeles").
            When provided, time-based groupings (e.g., DAY) and date filters are evaluated in this timezone;
            otherwise UTC is used.

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

        Returns
        -------
        HttpResponse[FeedbackTableResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/tables/feedback",
            method="POST",
            json={
                "timeGrouping": time_grouping,
                "fieldGroupings": convert_and_respect_annotation_metadata(
                    object_=field_groupings, annotation=typing.Sequence[FeedbackGroupBy], direction="write"
                ),
                "columnDefinitions": convert_and_respect_annotation_metadata(
                    object_=column_definitions, annotation=typing.Sequence[FeedbackColumnDefinition], direction="write"
                ),
                "feedbackFilter": convert_and_respect_annotation_metadata(
                    object_=feedback_filter, annotation=FeedbackFilter, direction="write"
                ),
                "timezone": timezone,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    FeedbackTableResponse,
                    parse_obj_as(
                        type_=FeedbackTableResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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_agent_user_table(
        self,
        *,
        column_definitions: typing.Sequence[AgentUserColumnDefinition],
        time_grouping: typing.Optional[TimeInterval] = OMIT,
        agent_user_filter: typing.Optional[AgentUserFilter] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentUserTableResponse]:
        """
        Retrieves structured agent user data formatted as a table, allowing users to group, filter,  and define specific metrics to display as columns.

        Parameters
        ----------
        column_definitions : typing.Sequence[AgentUserColumnDefinition]
            Specifies the metrics to be displayed as columns.
            Only the `count` metric is supported for agent user tables, so each table will have a single column definition using `count`.

        time_grouping : typing.Optional[TimeInterval]
            Defines the time interval for grouping data. If specified, data is grouped accordingly based on the time they were created.
             Example: If set to "DAY," data will be aggregated by day.

        agent_user_filter : typing.Optional[AgentUserFilter]
            Optional filter applied to refine the agent user data before processing.

        timezone : typing.Optional[str]
            IANA timezone identifier (e.g., "America/Los_Angeles").
            When provided, time-based groupings (e.g., DAY) and date filters are evaluated in this timezone;
            otherwise UTC is used.

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

        Returns
        -------
        HttpResponse[AgentUserTableResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/tables/agent-users",
            method="POST",
            json={
                "timeGrouping": time_grouping,
                "columnDefinitions": convert_and_respect_annotation_metadata(
                    object_=column_definitions, annotation=typing.Sequence[AgentUserColumnDefinition], direction="write"
                ),
                "agentUserFilter": convert_and_respect_annotation_metadata(
                    object_=agent_user_filter, annotation=AgentUserFilter, direction="write"
                ),
                "timezone": timezone,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentUserTableResponse,
                    parse_obj_as(
                        type_=AgentUserTableResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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 AsyncRawAnalyticsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def get_conversation_table(
        self,
        *,
        field_groupings: typing.Sequence[ConversationGroupBy],
        column_definitions: typing.Sequence[ConversationColumnDefinition],
        time_grouping: typing.Optional[TimeInterval] = OMIT,
        conversation_filter: typing.Optional[ConversationFilter] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ConversationTableResponse]:
        """
        Retrieves structured conversation data formatted as a table, allowing users to group, filter, and define specific metrics to display as columns.

        Parameters
        ----------
        field_groupings : typing.Sequence[ConversationGroupBy]
            Specifies the fields by which data should be grouped. Each unique combination forms a row.
            If multiple fields are provided, the result is grouped by their unique value combinations.
            If empty, all data is aggregated into a single row. |
            Note: The field `CreatedAt` should not be used here, all time-based grouping should be done using the `timeGrouping` field.

        column_definitions : typing.Sequence[ConversationColumnDefinition]
            Specifies the metrics to be displayed as columns. Column headers act as keys, with computed metric values as their mapped values. There needs to be at least one column definition in the table request.

        time_grouping : typing.Optional[TimeInterval]
            Defines the time interval for grouping data. If specified, data is grouped accordingly  based on the time they were created. Example: If set to "DAY," data will be aggregated by day.

        conversation_filter : typing.Optional[ConversationFilter]
            Optional filter applied to refine the conversation data before processing.

        timezone : typing.Optional[str]
            IANA timezone identifier (e.g., "America/Los_Angeles").
            When provided, time-based groupings (e.g., DAY) and date filters are evaluated in this timezone;
            otherwise UTC is used.

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

        Returns
        -------
        AsyncHttpResponse[ConversationTableResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/tables/conversations",
            method="POST",
            json={
                "timeGrouping": time_grouping,
                "fieldGroupings": convert_and_respect_annotation_metadata(
                    object_=field_groupings, annotation=typing.Sequence[ConversationGroupBy], direction="write"
                ),
                "columnDefinitions": convert_and_respect_annotation_metadata(
                    object_=column_definitions,
                    annotation=typing.Sequence[ConversationColumnDefinition],
                    direction="write",
                ),
                "conversationFilter": convert_and_respect_annotation_metadata(
                    object_=conversation_filter, annotation=ConversationFilter, direction="write"
                ),
                "timezone": timezone,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConversationTableResponse,
                    parse_obj_as(
                        type_=ConversationTableResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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_conversation_chart(
        self, *, request: ConversationChartRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[ChartResponse]:
        """
        Fetches conversation data visualized in a chart format. Supported chart types include pie chart, date histogram, and stacked bar charts.

        Parameters
        ----------
        request : ConversationChartRequest

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

        Returns
        -------
        AsyncHttpResponse[ChartResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/charts/conversations",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=ConversationChartRequest, direction="write"
            ),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ChartResponse,
                    parse_obj_as(
                        type_=ChartResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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_feedback_table(
        self,
        *,
        field_groupings: typing.Sequence[FeedbackGroupBy],
        column_definitions: typing.Sequence[FeedbackColumnDefinition],
        time_grouping: typing.Optional[TimeInterval] = OMIT,
        feedback_filter: typing.Optional[FeedbackFilter] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[FeedbackTableResponse]:
        """
        Retrieves structured feedback data formatted as a table, allowing users to group, filter,  and define specific metrics to display as columns.

        Parameters
        ----------
        field_groupings : typing.Sequence[FeedbackGroupBy]
            Specifies the fields by which data should be grouped. Each unique combination forms a row.
            If multiple fields are provided, the result is grouped by their unique value combinations.
            If empty, all data is aggregated into a single row.
            Note: The field CreatedAt should not be used here, all the time-based grouping should be done using the timeGrouping field.

        column_definitions : typing.Sequence[FeedbackColumnDefinition]
            Specifies the metrics to be displayed as columns.
            Column headers act as keys, with computed metric values as their mapped values.
            There needs to be at least one column definition in the table request.

        time_grouping : typing.Optional[TimeInterval]
            Defines the time interval for grouping data. If specified, data is grouped accordingly based on the time they were created.
             Example: If set to "DAY," data will be aggregated by day.

        feedback_filter : typing.Optional[FeedbackFilter]
            Optional filter applied to refine the feedback data before processing.

        timezone : typing.Optional[str]
            IANA timezone identifier (e.g., "America/Los_Angeles").
            When provided, time-based groupings (e.g., DAY) and date filters are evaluated in this timezone;
            otherwise UTC is used.

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

        Returns
        -------
        AsyncHttpResponse[FeedbackTableResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/tables/feedback",
            method="POST",
            json={
                "timeGrouping": time_grouping,
                "fieldGroupings": convert_and_respect_annotation_metadata(
                    object_=field_groupings, annotation=typing.Sequence[FeedbackGroupBy], direction="write"
                ),
                "columnDefinitions": convert_and_respect_annotation_metadata(
                    object_=column_definitions, annotation=typing.Sequence[FeedbackColumnDefinition], direction="write"
                ),
                "feedbackFilter": convert_and_respect_annotation_metadata(
                    object_=feedback_filter, annotation=FeedbackFilter, direction="write"
                ),
                "timezone": timezone,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    FeedbackTableResponse,
                    parse_obj_as(
                        type_=FeedbackTableResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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_agent_user_table(
        self,
        *,
        column_definitions: typing.Sequence[AgentUserColumnDefinition],
        time_grouping: typing.Optional[TimeInterval] = OMIT,
        agent_user_filter: typing.Optional[AgentUserFilter] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentUserTableResponse]:
        """
        Retrieves structured agent user data formatted as a table, allowing users to group, filter,  and define specific metrics to display as columns.

        Parameters
        ----------
        column_definitions : typing.Sequence[AgentUserColumnDefinition]
            Specifies the metrics to be displayed as columns.
            Only the `count` metric is supported for agent user tables, so each table will have a single column definition using `count`.

        time_grouping : typing.Optional[TimeInterval]
            Defines the time interval for grouping data. If specified, data is grouped accordingly based on the time they were created.
             Example: If set to "DAY," data will be aggregated by day.

        agent_user_filter : typing.Optional[AgentUserFilter]
            Optional filter applied to refine the agent user data before processing.

        timezone : typing.Optional[str]
            IANA timezone identifier (e.g., "America/Los_Angeles").
            When provided, time-based groupings (e.g., DAY) and date filters are evaluated in this timezone;
            otherwise UTC is used.

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

        Returns
        -------
        AsyncHttpResponse[AgentUserTableResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/tables/agent-users",
            method="POST",
            json={
                "timeGrouping": time_grouping,
                "columnDefinitions": convert_and_respect_annotation_metadata(
                    object_=column_definitions, annotation=typing.Sequence[AgentUserColumnDefinition], direction="write"
                ),
                "agentUserFilter": convert_and_respect_annotation_metadata(
                    object_=agent_user_filter, annotation=AgentUserFilter, direction="write"
                ),
                "timezone": timezone,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentUserTableResponse,
                    parse_obj_as(
                        type_=AgentUserTableResponse,  # 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(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # 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)
