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

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.datetime_utils import serialize_datetime
from ...core.http_response import AsyncHttpResponse, HttpResponse
from ...core.jsonable_encoder import jsonable_encoder
from ...core.request_options import RequestOptions
from ...core.serialization import convert_and_respect_annotation_metadata
from ...core.unchecked_base_model import construct_type
from ...errors.unprocessable_entity_error import UnprocessableEntityError
from ...types.create_order_request import CreateOrderRequest
from ...types.create_order_response import CreateOrderResponse
from ...types.list_orders_response import ListOrdersResponse
from ...types.order_id import OrderId
from ...types.order_request_state import OrderRequestState
from ...types.order_response import OrderResponse
from ...types.submit_order_response import SubmitOrderResponse
from ...types.update_order_request import UpdateOrderRequest
from ...types.update_order_response import UpdateOrderResponse

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


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

    def list(
        self,
        *,
        page_size: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        status: typing.Optional[typing.Union[OrderRequestState, typing.Sequence[OrderRequestState]]] = None,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListOrdersResponse]:
        """
        Lists Productions orders in the workspace. Supports filtering by status and date range, with pagination.

        Parameters
        ----------
        page_size : typing.Optional[int]
            Maximum number of orders to return per page.

        offset : typing.Optional[int]
            Number of orders to skip for pagination.

        status : typing.Optional[typing.Union[OrderRequestState, typing.Sequence[OrderRequestState]]]
            Filter orders by one or more statuses.

        start_date : typing.Optional[dt.datetime]
            Filter orders created on or after this date.

        end_date : typing.Optional[dt.datetime]
            Filter orders created on or before this date.

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

        Returns
        -------
        HttpResponse[ListOrdersResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/productions/orders",
            method="GET",
            params={
                "page_size": page_size,
                "offset": offset,
                "status": status,
                "start_date": serialize_datetime(start_date) if start_date is not None else None,
                "end_date": serialize_datetime(end_date) if end_date is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListOrdersResponse,
                    construct_type(
                        type_=ListOrdersResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create(
        self,
        *,
        request: typing.Optional[CreateOrderRequest] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateOrderResponse]:
        """
        Creates a new Productions order in the workspace. The order starts in the open state and can be configured with items before submission.

        Parameters
        ----------
        request : typing.Optional[CreateOrderRequest]

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

        Returns
        -------
        HttpResponse[CreateOrderResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/productions/orders",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=CreateOrderRequest, direction="write"
            ),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateOrderResponse,
                    construct_type(
                        type_=CreateOrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get(
        self, order_id: OrderId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[OrderResponse]:
        """
        Retrieves full details for a Productions order.

        Quote and pricing information may not be available immediately; if you wish to see the quote before submission, you may need to poll the order details until it is ready.

        Parameters
        ----------
        order_id : OrderId
            The ID of the order.

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

        Returns
        -------
        HttpResponse[OrderResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/productions/orders/{jsonable_encoder(order_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OrderResponse,
                    construct_type(
                        type_=OrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update(
        self, order_id: OrderId, *, request: UpdateOrderRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[UpdateOrderResponse]:
        """
        Updates an open order.

        Parameters
        ----------
        order_id : OrderId
            The ID of the order.

        request : UpdateOrderRequest

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

        Returns
        -------
        HttpResponse[UpdateOrderResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/productions/orders/{jsonable_encoder(order_id)}",
            method="PATCH",
            json={
                "request": convert_and_respect_annotation_metadata(
                    object_=request, annotation=UpdateOrderRequest, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateOrderResponse,
                    construct_type(
                        type_=UpdateOrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def submit(
        self, order_id: OrderId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[SubmitOrderResponse]:
        """
        Submits an open order for processing. The order must have at least one item. Once submitted, items can no longer be modified.

        Upon submission, the workspace will be charged for the order. The quote is based on information extracted from the uploaded media, such as its duration. The quote may not be available immediately; if you wish to see the quote before submission, you may need to poll the order details until the quote is ready.

        Parameters
        ----------
        order_id : OrderId
            The ID of the order.

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

        Returns
        -------
        HttpResponse[SubmitOrderResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/productions/orders/{jsonable_encoder(order_id)}/submit",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SubmitOrderResponse,
                    construct_type(
                        type_=SubmitOrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


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

    async def list(
        self,
        *,
        page_size: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        status: typing.Optional[typing.Union[OrderRequestState, typing.Sequence[OrderRequestState]]] = None,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListOrdersResponse]:
        """
        Lists Productions orders in the workspace. Supports filtering by status and date range, with pagination.

        Parameters
        ----------
        page_size : typing.Optional[int]
            Maximum number of orders to return per page.

        offset : typing.Optional[int]
            Number of orders to skip for pagination.

        status : typing.Optional[typing.Union[OrderRequestState, typing.Sequence[OrderRequestState]]]
            Filter orders by one or more statuses.

        start_date : typing.Optional[dt.datetime]
            Filter orders created on or after this date.

        end_date : typing.Optional[dt.datetime]
            Filter orders created on or before this date.

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

        Returns
        -------
        AsyncHttpResponse[ListOrdersResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/productions/orders",
            method="GET",
            params={
                "page_size": page_size,
                "offset": offset,
                "status": status,
                "start_date": serialize_datetime(start_date) if start_date is not None else None,
                "end_date": serialize_datetime(end_date) if end_date is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListOrdersResponse,
                    construct_type(
                        type_=ListOrdersResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create(
        self,
        *,
        request: typing.Optional[CreateOrderRequest] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateOrderResponse]:
        """
        Creates a new Productions order in the workspace. The order starts in the open state and can be configured with items before submission.

        Parameters
        ----------
        request : typing.Optional[CreateOrderRequest]

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

        Returns
        -------
        AsyncHttpResponse[CreateOrderResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/productions/orders",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=CreateOrderRequest, direction="write"
            ),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateOrderResponse,
                    construct_type(
                        type_=CreateOrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get(
        self, order_id: OrderId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[OrderResponse]:
        """
        Retrieves full details for a Productions order.

        Quote and pricing information may not be available immediately; if you wish to see the quote before submission, you may need to poll the order details until it is ready.

        Parameters
        ----------
        order_id : OrderId
            The ID of the order.

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

        Returns
        -------
        AsyncHttpResponse[OrderResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/productions/orders/{jsonable_encoder(order_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OrderResponse,
                    construct_type(
                        type_=OrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update(
        self, order_id: OrderId, *, request: UpdateOrderRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[UpdateOrderResponse]:
        """
        Updates an open order.

        Parameters
        ----------
        order_id : OrderId
            The ID of the order.

        request : UpdateOrderRequest

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

        Returns
        -------
        AsyncHttpResponse[UpdateOrderResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/productions/orders/{jsonable_encoder(order_id)}",
            method="PATCH",
            json={
                "request": convert_and_respect_annotation_metadata(
                    object_=request, annotation=UpdateOrderRequest, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateOrderResponse,
                    construct_type(
                        type_=UpdateOrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def submit(
        self, order_id: OrderId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[SubmitOrderResponse]:
        """
        Submits an open order for processing. The order must have at least one item. Once submitted, items can no longer be modified.

        Upon submission, the workspace will be charged for the order. The quote is based on information extracted from the uploaded media, such as its duration. The quote may not be available immediately; if you wish to see the quote before submission, you may need to poll the order details until the quote is ready.

        Parameters
        ----------
        order_id : OrderId
            The ID of the order.

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

        Returns
        -------
        AsyncHttpResponse[SubmitOrderResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/productions/orders/{jsonable_encoder(order_id)}/submit",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SubmitOrderResponse,
                    construct_type(
                        type_=SubmitOrderResponse,  # 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)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
