# 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.milestone_to_create_container import MilestoneToCreateContainer
from ..models.milestone_reviews_to_create_container import (
    MilestoneReviewsToCreateContainer,
)
from ..models.milestone_review_to_create_container import (
    MilestoneReviewToCreateContainer,
)
from ..models.milestone_list_container import MilestoneListContainer
from ..models.milestone_container import MilestoneContainer
from ..models.generic_result_deleted import GenericResultDeleted
from ..models.generic_result_created import GenericResultCreated


class MilestonesService(BaseService):

    @cast_models
    def get_milestones_by_contract(self, contract_id: str) -> MilestoneListContainer:
        """Retrieve a list of milestones found for a contract.

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

        Validator(str).validate(contract_id)

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

        response = self.send_request(serialized_request)

        return MilestoneListContainer._unmap(response)

    @cast_models
    def create_milestone(
        self, contract_id: str, request_body: MilestoneToCreateContainer = None
    ) -> GenericResultCreated:
        """Add a new milestone to contract.

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

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

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

    @cast_models
    def get_milestones_by_contract_and_id(
        self, contract_id: str, milestone_id: str
    ) -> MilestoneContainer:
        """Retrieve a single milestone.

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

        Validator(str).validate(contract_id)
        Validator(str).validate(milestone_id)

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

        response = self.send_request(serialized_request)

        return MilestoneContainer._unmap(response)

    @cast_models
    def delete_milestone_by_id(
        self, contract_id: str, milestone_id: str
    ) -> GenericResultDeleted:
        """Delete a single milestone from a contract.

        :param contract_id: Deel contract id.
        :type contract_id: str
        :param milestone_id: ID of milestone to return
        :type milestone_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(milestone_id)

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

        response = self.send_request(serialized_request)

        return GenericResultDeleted._unmap(response)

    @cast_models
    def create_milestone_review(
        self,
        contract_id: str,
        milestone_id: str,
        request_body: MilestoneReviewToCreateContainer = None,
    ) -> GenericResultCreated:
        """Review a milestone to approve or decline submitted work.

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

        Validator(MilestoneReviewToCreateContainer).is_optional().validate(request_body)
        Validator(str).validate(contract_id)
        Validator(str).validate(milestone_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/milestones/{{milestone_id}}/reviews",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .add_path("milestone_id", milestone_id)
            .serialize()
            .set_method("POST")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return GenericResultCreated._unmap(response)

    @cast_models
    def create_milestone_reviews(
        self, contract_id: str, request_body: MilestoneReviewsToCreateContainer = None
    ) -> GenericResultCreated:
        """Review a batch of milestones to approve or reject submitted work.

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

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

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/milestones/many/reviews",
                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 GenericResultCreated._unmap(response)
