# This file was generated by liblab | https://liblab.com/

from .utils.validator import Validator
from .utils.base_service import BaseService
from ..net.transport.serializer import Serializer
from ..models.utils.cast_models import cast_models
from ..models.timeoff_to_review_container import TimeoffToReviewContainer
from ..models.generic_result_updated import GenericResultUpdated
from ..models.generic_result_deleted import GenericResultDeleted
from ..models.eor_timeoffs_item_container import EorTimeoffsItemContainer
from ..models.eor_timeoffs_container import EorTimeoffsContainer
from ..models.eor_entitlements_container import EorEntitlementsContainer
from ..models.eor_client_timeoffs_container import EorClientTimeoffsContainer
from ..models.create_timeoff_container import CreateTimeoffContainer


class TimeOffService(BaseService):

    @cast_models
    def get_eor_time_offs(self, contract_id: str) -> EorTimeoffsContainer:
        """Retrieve the list of time off requests by an employee.

        :param contract_id: Deel contract id.
        :type contract_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: EorTimeoffsContainer
        """

        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/time-offs",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return EorTimeoffsContainer._unmap(response)

    @cast_models
    def create_eor_time_offs(
        self, contract_id: str, request_body: CreateTimeoffContainer = None
    ) -> EorTimeoffsItemContainer:
        """Add a time off request for a full-time employee.

        :param request_body: The request body., defaults to None
        :type request_body: CreateTimeoffContainer, optional
        :param contract_id: Deel contract id.
        :type contract_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: EorTimeoffsItemContainer
        """

        Validator(CreateTimeoffContainer).is_optional().validate(request_body)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/time-offs",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("POST")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return EorTimeoffsItemContainer._unmap(response)

    @cast_models
    def edit_eor_time_offs(
        self,
        contract_id: str,
        timeoff_id: str,
        request_body: CreateTimeoffContainer = None,
    ) -> EorTimeoffsItemContainer:
        """Edit a time off request for a full-time employee.

        :param request_body: The request body., defaults to None
        :type request_body: CreateTimeoffContainer, optional
        :param contract_id: Deel contract id.
        :type contract_id: str
        :param timeoff_id: Time off Id
        :type timeoff_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: EorTimeoffsItemContainer
        """

        Validator(CreateTimeoffContainer).is_optional().validate(request_body)
        Validator(str).validate(contract_id)
        Validator(str).validate(timeoff_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/time-offs/{{timeoff_id}}",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .add_path("timeoff_id", timeoff_id)
            .serialize()
            .set_method("PUT")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return EorTimeoffsItemContainer._unmap(response)

    @cast_models
    def delete_eor_time_offs(
        self, contract_id: str, timeoff_id: str
    ) -> GenericResultDeleted:
        """Cancel a time off request for an employee.

        :param contract_id: Deel contract id.
        :type contract_id: str
        :param timeoff_id: Time off Id
        :type timeoff_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GenericResultDeleted
        """

        Validator(str).validate(contract_id)
        Validator(str).validate(timeoff_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/time-offs/{{timeoff_id}}",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .add_path("timeoff_id", timeoff_id)
            .serialize()
            .set_method("DELETE")
        )

        response = self.send_request(serialized_request)

        return GenericResultDeleted._unmap(response)

    @cast_models
    def get_eor_entitlements(self, contract_id: str) -> EorEntitlementsContainer:
        """Retrieve a list of time off entitlements for a full-time employee.

        :param contract_id: Deel contract id.
        :type contract_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: EorEntitlementsContainer
        """

        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/entitlements",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return EorEntitlementsContainer._unmap(response)

    @cast_models
    def get_eor_client_time_offs(self) -> EorClientTimeoffsContainer:
        """List of time offs for all employees in your organization.

        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: successful operation
        :rtype: EorClientTimeoffsContainer
        """

        serialized_request = (
            Serializer(f"{self.base_url}/time-offs", self.get_default_headers())
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return EorClientTimeoffsContainer._unmap(response)

    @cast_models
    def review_timeoff(
        self, request_body: TimeoffToReviewContainer, timeoff_id: str
    ) -> GenericResultUpdated:
        """Approve or decline an employee's time off request.

        :param request_body: The request body.
        :type request_body: TimeoffToReviewContainer
        :param timeoff_id: Time off Id
        :type timeoff_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GenericResultUpdated
        """

        Validator(TimeoffToReviewContainer).validate(request_body)
        Validator(str).validate(timeoff_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/time-offs/{{timeoff_id}}/review",
                self.get_default_headers(),
            )
            .add_path("timeoff_id", timeoff_id)
            .serialize()
            .set_method("PATCH")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return GenericResultUpdated._unmap(response)
