# 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.off_cycle_payment_to_create_container import (
    OffCyclePaymentToCreateContainer,
)
from ..models.off_cycle_payment_list_container import OffCyclePaymentListContainer
from ..models.off_cycle_payment_container import OffCyclePaymentContainer
from ..models.generic_result_created_with_id import GenericResultCreatedWithId


class OffCyclePaymentsService(BaseService):

    @cast_models
    def get_off_cycle_payments_by_contract(
        self, contract_id: str
    ) -> OffCyclePaymentListContainer:
        """Retrieve a list of off-cycle payments for the given contract id.

        :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: OffCyclePaymentListContainer
        """

        Validator(str).validate(contract_id)

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

        response = self.send_request(serialized_request)

        return OffCyclePaymentListContainer._unmap(response)

    @cast_models
    def create_off_cycle_payment(
        self, contract_id: str, request_body: OffCyclePaymentToCreateContainer = None
    ) -> GenericResultCreatedWithId:
        """Add a new invoice line-item for the purpose of off-cycle payment for a given contract.

        :param request_body: The request body., defaults to None
        :type request_body: OffCyclePaymentToCreateContainer, 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: GenericResultCreatedWithId
        """

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

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/off-cycle-payments",
                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 GenericResultCreatedWithId._unmap(response)

    @cast_models
    def get_off_cycle_payment_by_contract_and_id(
        self, contract_id: str, offcycle_payment_id: str
    ) -> OffCyclePaymentContainer:
        """Retrieve a single off-cycle payment.

        :param contract_id: Deel contract id.
        :type contract_id: str
        :param offcycle_payment_id: ID of off-cycle payment to return
        :type offcycle_payment_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: OffCyclePaymentContainer
        """

        Validator(str).validate(contract_id)
        Validator(str).validate(offcycle_payment_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/off-cycle-payments/{{offcycle_payment_id}}",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .add_path("offcycle_payment_id", offcycle_payment_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return OffCyclePaymentContainer._unmap(response)
