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

import typing
from ...core.client_wrapper import SyncClientWrapper
from .raw_client import RawShiftsClient
from ...requests.shift import ShiftParams
from ...core.request_options import RequestOptions
from ...types.create_shift_response import CreateShiftResponse
from ...requests.shift_query import ShiftQueryParams
from ...types.search_shifts_response import SearchShiftsResponse
from ...types.get_shift_response import GetShiftResponse
from ...types.update_shift_response import UpdateShiftResponse
from ...types.delete_shift_response import DeleteShiftResponse
from ...core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawShiftsClient

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


class ShiftsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawShiftsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawShiftsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawShiftsClient
        """
        return self._raw_client

    def create(
        self,
        *,
        shift: ShiftParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateShiftResponse:
        """
        Creates a new `Shift`.

        A `Shift` represents a complete workday for a single team member.
        You must provide the following values in your request to this
        endpoint:

        - `location_id`
        - `team_member_id`
        - `start_at`

        An attempt to create a new `Shift` can result in a `BAD_REQUEST` error when:
        - The `status` of the new `Shift` is `OPEN` and the team member has another
        shift with an `OPEN` status.
        - The `start_at` date is in the future.
        - The `start_at` or `end_at` date overlaps another shift for the same team member.
        - The `Break` instances are set in the request and a break `start_at`
        is before the `Shift.start_at`, a break `end_at` is after
        the `Shift.end_at`, or both.

        Parameters
        ----------
        shift : ShiftParams
            The `Shift` to be created.

        idempotency_key : typing.Optional[str]
            A unique string value to ensure the idempotency of the operation.

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

        Returns
        -------
        CreateShiftResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.labor.shifts.create(
            idempotency_key="HIDSNG5KS478L",
            shift={
                "location_id": "PAA1RJZZKXBFG",
                "start_at": "2019-01-25T03:11:00-05:00",
                "end_at": "2019-01-25T13:11:00-05:00",
                "wage": {
                    "title": "Barista",
                    "hourly_rate": {"amount": 1100, "currency": "USD"},
                    "tip_eligible": True,
                },
                "breaks": [
                    {
                        "start_at": "2019-01-25T06:11:00-05:00",
                        "end_at": "2019-01-25T06:16:00-05:00",
                        "break_type_id": "REGS1EQR1TPZ5",
                        "name": "Tea Break",
                        "expected_duration": "PT5M",
                        "is_paid": True,
                    }
                ],
                "team_member_id": "ormj0jJJZ5OZIzxrZYJI",
                "declared_cash_tip_money": {"amount": 500, "currency": "USD"},
            },
        )
        """
        response = self._raw_client.create(
            shift=shift, idempotency_key=idempotency_key, request_options=request_options
        )
        return response.data

    def search(
        self,
        *,
        query: typing.Optional[ShiftQueryParams] = OMIT,
        limit: typing.Optional[int] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SearchShiftsResponse:
        """
        Returns a paginated list of `Shift` records for a business.
        The list to be returned can be filtered by:
        - Location IDs
        - Team member IDs
        - Shift status (`OPEN` or `CLOSED`)
        - Shift start
        - Shift end
        - Workday details

        The list can be sorted by:
        - `START_AT`
        - `END_AT`
        - `CREATED_AT`
        - `UPDATED_AT`

        Parameters
        ----------
        query : typing.Optional[ShiftQueryParams]
            Query filters.

        limit : typing.Optional[int]
            The number of resources in a page (200 by default).

        cursor : typing.Optional[str]
            An opaque cursor for fetching the next page.

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

        Returns
        -------
        SearchShiftsResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.labor.shifts.search(
            query={
                "filter": {
                    "workday": {
                        "date_range": {
                            "start_date": "2019-01-20",
                            "end_date": "2019-02-03",
                        },
                        "match_shifts_by": "START_AT",
                        "default_timezone": "America/Los_Angeles",
                    }
                }
            },
            limit=100,
        )
        """
        response = self._raw_client.search(query=query, limit=limit, cursor=cursor, request_options=request_options)
        return response.data

    def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetShiftResponse:
        """
        Returns a single `Shift` specified by `id`.

        Parameters
        ----------
        id : str
            The UUID for the `Shift` being retrieved.

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

        Returns
        -------
        GetShiftResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.labor.shifts.get(
            id="id",
        )
        """
        response = self._raw_client.get(id, request_options=request_options)
        return response.data

    def update(
        self, id: str, *, shift: ShiftParams, request_options: typing.Optional[RequestOptions] = None
    ) -> UpdateShiftResponse:
        """
        Updates an existing `Shift`.

        When adding a `Break` to a `Shift`, any earlier `Break` instances in the `Shift` have
        the `end_at` property set to a valid RFC-3339 datetime string.

        When closing a `Shift`, all `Break` instances in the `Shift` must be complete with `end_at`
        set on each `Break`.

        Parameters
        ----------
        id : str
            The ID of the object being updated.

        shift : ShiftParams
            The updated `Shift` object.

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

        Returns
        -------
        UpdateShiftResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.labor.shifts.update(
            id="id",
            shift={
                "location_id": "PAA1RJZZKXBFG",
                "start_at": "2019-01-25T03:11:00-05:00",
                "end_at": "2019-01-25T13:11:00-05:00",
                "wage": {
                    "title": "Bartender",
                    "hourly_rate": {"amount": 1500, "currency": "USD"},
                    "tip_eligible": True,
                },
                "breaks": [
                    {
                        "id": "X7GAQYVVRRG6P",
                        "start_at": "2019-01-25T06:11:00-05:00",
                        "end_at": "2019-01-25T06:16:00-05:00",
                        "break_type_id": "REGS1EQR1TPZ5",
                        "name": "Tea Break",
                        "expected_duration": "PT5M",
                        "is_paid": True,
                    }
                ],
                "version": 1,
                "team_member_id": "ormj0jJJZ5OZIzxrZYJI",
                "declared_cash_tip_money": {"amount": 500, "currency": "USD"},
            },
        )
        """
        response = self._raw_client.update(id, shift=shift, request_options=request_options)
        return response.data

    def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DeleteShiftResponse:
        """
        Deletes a `Shift`.

        Parameters
        ----------
        id : str
            The UUID for the `Shift` being deleted.

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

        Returns
        -------
        DeleteShiftResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.labor.shifts.delete(
            id="id",
        )
        """
        response = self._raw_client.delete(id, request_options=request_options)
        return response.data


class AsyncShiftsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawShiftsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawShiftsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawShiftsClient
        """
        return self._raw_client

    async def create(
        self,
        *,
        shift: ShiftParams,
        idempotency_key: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateShiftResponse:
        """
        Creates a new `Shift`.

        A `Shift` represents a complete workday for a single team member.
        You must provide the following values in your request to this
        endpoint:

        - `location_id`
        - `team_member_id`
        - `start_at`

        An attempt to create a new `Shift` can result in a `BAD_REQUEST` error when:
        - The `status` of the new `Shift` is `OPEN` and the team member has another
        shift with an `OPEN` status.
        - The `start_at` date is in the future.
        - The `start_at` or `end_at` date overlaps another shift for the same team member.
        - The `Break` instances are set in the request and a break `start_at`
        is before the `Shift.start_at`, a break `end_at` is after
        the `Shift.end_at`, or both.

        Parameters
        ----------
        shift : ShiftParams
            The `Shift` to be created.

        idempotency_key : typing.Optional[str]
            A unique string value to ensure the idempotency of the operation.

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

        Returns
        -------
        CreateShiftResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.labor.shifts.create(
                idempotency_key="HIDSNG5KS478L",
                shift={
                    "location_id": "PAA1RJZZKXBFG",
                    "start_at": "2019-01-25T03:11:00-05:00",
                    "end_at": "2019-01-25T13:11:00-05:00",
                    "wage": {
                        "title": "Barista",
                        "hourly_rate": {"amount": 1100, "currency": "USD"},
                        "tip_eligible": True,
                    },
                    "breaks": [
                        {
                            "start_at": "2019-01-25T06:11:00-05:00",
                            "end_at": "2019-01-25T06:16:00-05:00",
                            "break_type_id": "REGS1EQR1TPZ5",
                            "name": "Tea Break",
                            "expected_duration": "PT5M",
                            "is_paid": True,
                        }
                    ],
                    "team_member_id": "ormj0jJJZ5OZIzxrZYJI",
                    "declared_cash_tip_money": {"amount": 500, "currency": "USD"},
                },
            )


        asyncio.run(main())
        """
        response = await self._raw_client.create(
            shift=shift, idempotency_key=idempotency_key, request_options=request_options
        )
        return response.data

    async def search(
        self,
        *,
        query: typing.Optional[ShiftQueryParams] = OMIT,
        limit: typing.Optional[int] = OMIT,
        cursor: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SearchShiftsResponse:
        """
        Returns a paginated list of `Shift` records for a business.
        The list to be returned can be filtered by:
        - Location IDs
        - Team member IDs
        - Shift status (`OPEN` or `CLOSED`)
        - Shift start
        - Shift end
        - Workday details

        The list can be sorted by:
        - `START_AT`
        - `END_AT`
        - `CREATED_AT`
        - `UPDATED_AT`

        Parameters
        ----------
        query : typing.Optional[ShiftQueryParams]
            Query filters.

        limit : typing.Optional[int]
            The number of resources in a page (200 by default).

        cursor : typing.Optional[str]
            An opaque cursor for fetching the next page.

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

        Returns
        -------
        SearchShiftsResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.labor.shifts.search(
                query={
                    "filter": {
                        "workday": {
                            "date_range": {
                                "start_date": "2019-01-20",
                                "end_date": "2019-02-03",
                            },
                            "match_shifts_by": "START_AT",
                            "default_timezone": "America/Los_Angeles",
                        }
                    }
                },
                limit=100,
            )


        asyncio.run(main())
        """
        response = await self._raw_client.search(
            query=query, limit=limit, cursor=cursor, request_options=request_options
        )
        return response.data

    async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetShiftResponse:
        """
        Returns a single `Shift` specified by `id`.

        Parameters
        ----------
        id : str
            The UUID for the `Shift` being retrieved.

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

        Returns
        -------
        GetShiftResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.labor.shifts.get(
                id="id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.get(id, request_options=request_options)
        return response.data

    async def update(
        self, id: str, *, shift: ShiftParams, request_options: typing.Optional[RequestOptions] = None
    ) -> UpdateShiftResponse:
        """
        Updates an existing `Shift`.

        When adding a `Break` to a `Shift`, any earlier `Break` instances in the `Shift` have
        the `end_at` property set to a valid RFC-3339 datetime string.

        When closing a `Shift`, all `Break` instances in the `Shift` must be complete with `end_at`
        set on each `Break`.

        Parameters
        ----------
        id : str
            The ID of the object being updated.

        shift : ShiftParams
            The updated `Shift` object.

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

        Returns
        -------
        UpdateShiftResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.labor.shifts.update(
                id="id",
                shift={
                    "location_id": "PAA1RJZZKXBFG",
                    "start_at": "2019-01-25T03:11:00-05:00",
                    "end_at": "2019-01-25T13:11:00-05:00",
                    "wage": {
                        "title": "Bartender",
                        "hourly_rate": {"amount": 1500, "currency": "USD"},
                        "tip_eligible": True,
                    },
                    "breaks": [
                        {
                            "id": "X7GAQYVVRRG6P",
                            "start_at": "2019-01-25T06:11:00-05:00",
                            "end_at": "2019-01-25T06:16:00-05:00",
                            "break_type_id": "REGS1EQR1TPZ5",
                            "name": "Tea Break",
                            "expected_duration": "PT5M",
                            "is_paid": True,
                        }
                    ],
                    "version": 1,
                    "team_member_id": "ormj0jJJZ5OZIzxrZYJI",
                    "declared_cash_tip_money": {"amount": 500, "currency": "USD"},
                },
            )


        asyncio.run(main())
        """
        response = await self._raw_client.update(id, shift=shift, request_options=request_options)
        return response.data

    async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DeleteShiftResponse:
        """
        Deletes a `Shift`.

        Parameters
        ----------
        id : str
            The UUID for the `Shift` being deleted.

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

        Returns
        -------
        DeleteShiftResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.labor.shifts.delete(
                id="id",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.delete(id, request_options=request_options)
        return response.data
