# 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.output_to_create_file_ref_container import OutputToCreateFileRefContainer
from ..models.input_to_create_file_ref import InputToCreateFileRef
from ..models.generic_result_updated import GenericResultUpdated
from ..models.generic_result_deleted import GenericResultDeleted
from ..models.adjustments_container import AdjustmentsContainer
from ..models.adjustments_categories_container import AdjustmentsCategoriesContainer
from ..models.adjustment_to_update_container import AdjustmentToUpdateContainer
from ..models.adjustment_to_create_container import AdjustmentToCreateContainer
from ..models.adjustment_created_container import AdjustmentCreatedContainer


class AdjustmentsService(BaseService):

    @cast_models
    def create_adjustment(self, request_body: dict) -> AdjustmentCreatedContainer:
        """Create a new adjustment.

        :param request_body: The request body.
        :type request_body: dict
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: AdjustmentCreatedContainer
        """

        Validator(dict).validate(request_body)

        serialized_request = (
            Serializer(f"{self.base_url}/adjustments", self.get_default_headers())
            .serialize()
            .set_method("POST")
            .set_body(request_body, "multipart/form-data")
        )

        response = self.send_request(serialized_request)

        return AdjustmentCreatedContainer._unmap(response)

    @cast_models
    def get_adjustments_by_id(self, adjustment_id: str) -> AdjustmentCreatedContainer:
        """Retrieve an adjustment.

        :param adjustment_id: Adjustment id.
        :type adjustment_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: AdjustmentCreatedContainer
        """

        Validator(str).validate(adjustment_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/adjustments/{{adjustment_id}}",
                self.get_default_headers(),
            )
            .add_path("adjustment_id", adjustment_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return AdjustmentCreatedContainer._unmap(response)

    @cast_models
    def update_adjustment(
        self, request_body: AdjustmentToUpdateContainer, adjustment_id: str
    ) -> GenericResultUpdated:
        """Update an adjustment.

        :param request_body: The request body.
        :type request_body: AdjustmentToUpdateContainer
        :param adjustment_id: Adjustment id.
        :type adjustment_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GenericResultUpdated
        """

        Validator(AdjustmentToUpdateContainer).validate(request_body)
        Validator(str).validate(adjustment_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/adjustments/{{adjustment_id}}",
                self.get_default_headers(),
            )
            .add_path("adjustment_id", adjustment_id)
            .serialize()
            .set_method("PATCH")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return GenericResultUpdated._unmap(response)

    @cast_models
    def delete_adjustment(self, adjustment_id: str) -> GenericResultDeleted:
        """Delete an adjustment.

        :param adjustment_id: Adjustment id.
        :type adjustment_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GenericResultDeleted
        """

        Validator(str).validate(adjustment_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/adjustments/{{adjustment_id}}",
                self.get_default_headers(),
            )
            .add_path("adjustment_id", adjustment_id)
            .serialize()
            .set_method("DELETE")
        )

        response = self.send_request(serialized_request)

        return GenericResultDeleted._unmap(response)

    @cast_models
    def get_categories(self) -> AdjustmentsCategoriesContainer:
        """Get all categories for your organization.

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

        serialized_request = (
            Serializer(
                f"{self.base_url}/adjustments/categories", self.get_default_headers()
            )
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return AdjustmentsCategoriesContainer._unmap(response)

    @cast_models
    def create_file_ref(
        self, request_body: InputToCreateFileRef
    ) -> OutputToCreateFileRefContainer:
        """Upload file to Deel storage to use the file attachment feature for other endpoints.

        :param request_body: The request body.
        :type request_body: InputToCreateFileRef
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: OutputToCreateFileRefContainer
        """

        Validator(InputToCreateFileRef).validate(request_body)

        serialized_request = (
            Serializer(f"{self.base_url}/attachments", self.get_default_headers())
            .serialize()
            .set_method("POST")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return OutputToCreateFileRefContainer._unmap(response)

    @cast_models
    def get_adjustments(
        self, contract_id: str, from_: str = None, to: str = None
    ) -> AdjustmentsContainer:
        """Get all adjustments for the specific contract.

        :param contract_id: Deel contract id.
        :type contract_id: str
        :param from_: Filter adjustments by start date., defaults to None
        :type from_: str, optional
        :param to: Filter adjustments by end date., defaults to None
        :type to: str, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: AdjustmentsContainer
        """

        Validator(str).validate(contract_id)
        Validator(str).is_optional().validate(from_)
        Validator(str).is_optional().validate(to)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/adjustments",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .add_query("from", from_)
            .add_query("to", to)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return AdjustmentsContainer._unmap(response)
