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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.unchecked_base_model import construct_type
from .types.create_actions_request_filters import CreateActionsRequestFilters
from .types.create_actions_request_id import CreateActionsRequestId
from .types.create_actions_request_ordering_item import CreateActionsRequestOrderingItem
from .types.create_actions_request_selected_items import CreateActionsRequestSelectedItems
from .types.list_actions_response_item import ListActionsResponseItem

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


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

    def list(
        self, *, project: int, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[ListActionsResponseItem]]:
        """
        Retrieve all the registered actions with descriptions that data manager can use.

        Parameters
        ----------
        project : int
            Project ID

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

        Returns
        -------
        HttpResponse[typing.List[ListActionsResponseItem]]
            Actions retrieved successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/dm/actions/",
            method="GET",
            params={
                "project": project,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[ListActionsResponseItem],
                    construct_type(
                        type_=typing.List[ListActionsResponseItem],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _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,
        *,
        id: CreateActionsRequestId,
        project: int,
        view: typing.Optional[int] = None,
        filters: typing.Optional[CreateActionsRequestFilters] = OMIT,
        ordering: typing.Optional[typing.Sequence[CreateActionsRequestOrderingItem]] = OMIT,
        selected_items: typing.Optional[CreateActionsRequestSelectedItems] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Perform a Data Manager action with the selected tasks and filters. Note: More complex actions require additional parameters in the request body. Call `GET api/actions?project=<id>` to explore them. <br>Example: `GET api/actions?id=delete_tasks&project=1`

        Parameters
        ----------
        id : CreateActionsRequestId
            Action name ID, see the full list of actions in the `GET api/actions` request

        project : int
            Project ID

        view : typing.Optional[int]
            View ID (optional, it has higher priority than filters, selectedItems and ordering from the request body payload)

        filters : typing.Optional[CreateActionsRequestFilters]
            Filters to apply on tasks. You can use [the helper class `Filters` from this page](https://labelstud.io/sdk/data_manager.html) to create Data Manager Filters.<br>Example: `{"conjunction": "or", "items": [{"filter": "filter:tasks:completed_at", "operator": "greater", "type": "Datetime", "value": "2021-01-01T00:00:00.000Z"}]}`

        ordering : typing.Optional[typing.Sequence[CreateActionsRequestOrderingItem]]
            List of fields to order by. Fields are similar to filters but without the `filter:` prefix. To reverse the order, add a minus sign before the field name, e.g. `-tasks:created_at`.

        selected_items : typing.Optional[CreateActionsRequestSelectedItems]
            Task selection by IDs. If filters are applied, the selection will be applied to the filtered tasks.If "all" is `false`, `"included"` must be used. If "all" is `true`, `"excluded"` must be used.<br>Examples: `{"all": false, "included": [1, 2, 3]}` or `{"all": true, "excluded": [4, 5]}`

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/dm/actions/",
            method="POST",
            params={
                "id": id,
                "project": project,
                "view": view,
            },
            json={
                "filters": convert_and_respect_annotation_metadata(
                    object_=filters, annotation=CreateActionsRequestFilters, direction="write"
                ),
                "ordering": ordering,
                "selectedItems": convert_and_respect_annotation_metadata(
                    object_=selected_items, annotation=CreateActionsRequestSelectedItems, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            _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 AsyncRawActionsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self, *, project: int, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[ListActionsResponseItem]]:
        """
        Retrieve all the registered actions with descriptions that data manager can use.

        Parameters
        ----------
        project : int
            Project ID

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

        Returns
        -------
        AsyncHttpResponse[typing.List[ListActionsResponseItem]]
            Actions retrieved successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/dm/actions/",
            method="GET",
            params={
                "project": project,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[ListActionsResponseItem],
                    construct_type(
                        type_=typing.List[ListActionsResponseItem],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _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,
        *,
        id: CreateActionsRequestId,
        project: int,
        view: typing.Optional[int] = None,
        filters: typing.Optional[CreateActionsRequestFilters] = OMIT,
        ordering: typing.Optional[typing.Sequence[CreateActionsRequestOrderingItem]] = OMIT,
        selected_items: typing.Optional[CreateActionsRequestSelectedItems] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Perform a Data Manager action with the selected tasks and filters. Note: More complex actions require additional parameters in the request body. Call `GET api/actions?project=<id>` to explore them. <br>Example: `GET api/actions?id=delete_tasks&project=1`

        Parameters
        ----------
        id : CreateActionsRequestId
            Action name ID, see the full list of actions in the `GET api/actions` request

        project : int
            Project ID

        view : typing.Optional[int]
            View ID (optional, it has higher priority than filters, selectedItems and ordering from the request body payload)

        filters : typing.Optional[CreateActionsRequestFilters]
            Filters to apply on tasks. You can use [the helper class `Filters` from this page](https://labelstud.io/sdk/data_manager.html) to create Data Manager Filters.<br>Example: `{"conjunction": "or", "items": [{"filter": "filter:tasks:completed_at", "operator": "greater", "type": "Datetime", "value": "2021-01-01T00:00:00.000Z"}]}`

        ordering : typing.Optional[typing.Sequence[CreateActionsRequestOrderingItem]]
            List of fields to order by. Fields are similar to filters but without the `filter:` prefix. To reverse the order, add a minus sign before the field name, e.g. `-tasks:created_at`.

        selected_items : typing.Optional[CreateActionsRequestSelectedItems]
            Task selection by IDs. If filters are applied, the selection will be applied to the filtered tasks.If "all" is `false`, `"included"` must be used. If "all" is `true`, `"excluded"` must be used.<br>Examples: `{"all": false, "included": [1, 2, 3]}` or `{"all": true, "excluded": [4, 5]}`

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/dm/actions/",
            method="POST",
            params={
                "id": id,
                "project": project,
                "view": view,
            },
            json={
                "filters": convert_and_respect_annotation_metadata(
                    object_=filters, annotation=CreateActionsRequestFilters, direction="write"
                ),
                "ordering": ordering,
                "selectedItems": convert_and_respect_annotation_metadata(
                    object_=selected_items, annotation=CreateActionsRequestSelectedItems, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            _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)
