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

import typing
from ..core.client_wrapper import SyncClientWrapper
from .types.conversation_group_by import ConversationGroupBy
from .types.conversation_column_definition import ConversationColumnDefinition
from .types.time_interval import TimeInterval
from ..conversation.types.conversation_filter import ConversationFilter
from ..core.request_options import RequestOptions
from .types.conversation_table_response import ConversationTableResponse
from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.pydantic_utilities import parse_obj_as
from ..commons.errors.not_found_error import NotFoundError
from ..commons.types.error_message import ErrorMessage
from ..commons.errors.bad_request_error import BadRequestError
from ..commons.errors.server_error import ServerError
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from .types.conversation_chart_request import ConversationChartRequest
from .types.chart_response import ChartResponse
from .types.feedback_group_by import FeedbackGroupBy
from .types.feedback_column_definition import FeedbackColumnDefinition
from ..conversation.types.feedback_filter import FeedbackFilter
from .types.feedback_table_response import FeedbackTableResponse
from ..core.client_wrapper import AsyncClientWrapper

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


class AnalyticsClient:
    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,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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.

        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.

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

        Returns
        -------
        ConversationTableResponse

        Examples
        --------
        from mavenagi import MavenAGI
        from mavenagi.analytics import (
            ConversationColumnDefinition,
            ConversationGroupBy,
            ConversationMetric_Average,
            ConversationMetric_Count,
            ConversationMetric_Percentile,
        )
        from mavenagi.conversation import ConversationFilter

        client = MavenAGI(
            organization_id="YOUR_ORGANIZATION_ID",
            agent_id="YOUR_AGENT_ID",
            app_id="YOUR_APP_ID",
            app_secret="YOUR_APP_SECRET",
        )
        client.analytics.get_conversation_table(
            conversation_filter=ConversationFilter(
                languages=["en", "es"],
            ),
            time_grouping="DAY",
            field_groupings=[
                ConversationGroupBy(
                    field="Category",
                )
            ],
            column_definitions=[
                ConversationColumnDefinition(
                    header="count",
                    metric=ConversationMetric_Count(),
                ),
                ConversationColumnDefinition(
                    header="avg_first_response_time",
                    metric=ConversationMetric_Average(
                        target_field="FirstResponseTime",
                    ),
                ),
                ConversationColumnDefinition(
                    header="percentile_handle_time",
                    metric=ConversationMetric_Percentile(
                        target_field="HandleTime",
                        percentile=25.0,
                    ),
                ),
            ],
        )
        """
        _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"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ConversationTableResponse,
                    parse_obj_as(
                        type_=ConversationTableResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise ServerError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_conversation_chart(
        self, *, request: ConversationChartRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        ChartResponse

        Examples
        --------
        from mavenagi import MavenAGI
        from mavenagi.analytics import (
            ConversationChartRequest_PieChart,
            ConversationGroupBy,
            ConversationMetric_Count,
        )
        from mavenagi.conversation import ConversationFilter

        client = MavenAGI(
            organization_id="YOUR_ORGANIZATION_ID",
            agent_id="YOUR_AGENT_ID",
            app_id="YOUR_APP_ID",
            app_secret="YOUR_APP_SECRET",
        )
        client.analytics.get_conversation_chart(
            request=ConversationChartRequest_PieChart(
                conversation_filter=ConversationFilter(
                    languages=["en", "es"],
                ),
                group_by=ConversationGroupBy(
                    field="Category",
                ),
                metric=ConversationMetric_Count(),
            ),
        )
        """
        _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:
                return typing.cast(
                    ChartResponse,
                    parse_obj_as(
                        type_=ChartResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise ServerError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, 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,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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.

        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.

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

        Returns
        -------
        FeedbackTableResponse

        Examples
        --------
        from mavenagi import MavenAGI
        from mavenagi.analytics import (
            FeedbackColumnDefinition,
            FeedbackGroupBy,
            FeedbackMetric_Count,
        )
        from mavenagi.conversation import FeedbackFilter

        client = MavenAGI(
            organization_id="YOUR_ORGANIZATION_ID",
            agent_id="YOUR_AGENT_ID",
            app_id="YOUR_APP_ID",
            app_secret="YOUR_APP_SECRET",
        )
        client.analytics.get_feedback_table(
            feedback_filter=FeedbackFilter(
                types=["THUMBS_UP", "INSERT"],
            ),
            field_groupings=[
                FeedbackGroupBy(
                    field="CreatedBy",
                )
            ],
            column_definitions=[
                FeedbackColumnDefinition(
                    header="feedback_count",
                    metric=FeedbackMetric_Count(),
                )
            ],
        )
        """
        _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"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    FeedbackTableResponse,
                    parse_obj_as(
                        type_=FeedbackTableResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise ServerError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncAnalyticsClient:
    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,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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.

        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.

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

        Returns
        -------
        ConversationTableResponse

        Examples
        --------
        import asyncio

        from mavenagi import AsyncMavenAGI
        from mavenagi.analytics import (
            ConversationColumnDefinition,
            ConversationGroupBy,
            ConversationMetric_Average,
            ConversationMetric_Count,
            ConversationMetric_Percentile,
        )
        from mavenagi.conversation import ConversationFilter

        client = AsyncMavenAGI(
            organization_id="YOUR_ORGANIZATION_ID",
            agent_id="YOUR_AGENT_ID",
            app_id="YOUR_APP_ID",
            app_secret="YOUR_APP_SECRET",
        )


        async def main() -> None:
            await client.analytics.get_conversation_table(
                conversation_filter=ConversationFilter(
                    languages=["en", "es"],
                ),
                time_grouping="DAY",
                field_groupings=[
                    ConversationGroupBy(
                        field="Category",
                    )
                ],
                column_definitions=[
                    ConversationColumnDefinition(
                        header="count",
                        metric=ConversationMetric_Count(),
                    ),
                    ConversationColumnDefinition(
                        header="avg_first_response_time",
                        metric=ConversationMetric_Average(
                            target_field="FirstResponseTime",
                        ),
                    ),
                    ConversationColumnDefinition(
                        header="percentile_handle_time",
                        metric=ConversationMetric_Percentile(
                            target_field="HandleTime",
                            percentile=25.0,
                        ),
                    ),
                ],
            )


        asyncio.run(main())
        """
        _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"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ConversationTableResponse,
                    parse_obj_as(
                        type_=ConversationTableResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise ServerError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_conversation_chart(
        self, *, request: ConversationChartRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        ChartResponse

        Examples
        --------
        import asyncio

        from mavenagi import AsyncMavenAGI
        from mavenagi.analytics import (
            ConversationChartRequest_PieChart,
            ConversationGroupBy,
            ConversationMetric_Count,
        )
        from mavenagi.conversation import ConversationFilter

        client = AsyncMavenAGI(
            organization_id="YOUR_ORGANIZATION_ID",
            agent_id="YOUR_AGENT_ID",
            app_id="YOUR_APP_ID",
            app_secret="YOUR_APP_SECRET",
        )


        async def main() -> None:
            await client.analytics.get_conversation_chart(
                request=ConversationChartRequest_PieChart(
                    conversation_filter=ConversationFilter(
                        languages=["en", "es"],
                    ),
                    group_by=ConversationGroupBy(
                        field="Category",
                    ),
                    metric=ConversationMetric_Count(),
                ),
            )


        asyncio.run(main())
        """
        _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:
                return typing.cast(
                    ChartResponse,
                    parse_obj_as(
                        type_=ChartResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise ServerError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, 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,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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.

        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.

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

        Returns
        -------
        FeedbackTableResponse

        Examples
        --------
        import asyncio

        from mavenagi import AsyncMavenAGI
        from mavenagi.analytics import (
            FeedbackColumnDefinition,
            FeedbackGroupBy,
            FeedbackMetric_Count,
        )
        from mavenagi.conversation import FeedbackFilter

        client = AsyncMavenAGI(
            organization_id="YOUR_ORGANIZATION_ID",
            agent_id="YOUR_AGENT_ID",
            app_id="YOUR_APP_ID",
            app_secret="YOUR_APP_SECRET",
        )


        async def main() -> None:
            await client.analytics.get_feedback_table(
                feedback_filter=FeedbackFilter(
                    types=["THUMBS_UP", "INSERT"],
                ),
                field_groupings=[
                    FeedbackGroupBy(
                        field="CreatedBy",
                    )
                ],
                column_definitions=[
                    FeedbackColumnDefinition(
                        header="feedback_count",
                        metric=FeedbackMetric_Count(),
                    )
                ],
            )


        asyncio.run(main())
        """
        _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"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    FeedbackTableResponse,
                    parse_obj_as(
                        type_=FeedbackTableResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise ServerError(
                    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, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
