# 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.task_list_container import TaskListContainer
from ..models.task_created_container import TaskCreatedContainer
from ..models.request_body_to_create_pgo_task_reviews_reviews_container import (
    RequestBodyToCreatePgoTaskReviewsReviewsContainer,
)
from ..models.request_body_to_create_pgo_task_reviews_by_id_reviews_container import (
    RequestBodyToCreatePgoTaskReviewsByIdReviewsContainer,
)
from ..models.input_to_create_pgo_task import InputToCreatePgoTask
from ..models.generic_result_deleted import GenericResultDeleted


class TasksService(BaseService):

    @cast_models
    def get_tasks_by_contract(self, contract_id: str) -> TaskListContainer:
        """Retrieve a list of tasks for a given 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: TaskListContainer
        """

        Validator(str).validate(contract_id)

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

        response = self.send_request(serialized_request)

        return TaskListContainer._unmap(response)

    @cast_models
    def create_contract_pgo_tak(
        self, request_body: InputToCreatePgoTask, contract_id: str
    ) -> TaskCreatedContainer:
        """Create a new task for the contractor.

        :param request_body: The request body.
        :type request_body: InputToCreatePgoTask
        :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: TaskCreatedContainer
        """

        Validator(InputToCreatePgoTask).validate(request_body)
        Validator(str).validate(contract_id)

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

    @cast_models
    def create_task_many_review(
        self,
        contract_id: str,
        request_body: RequestBodyToCreatePgoTaskReviewsReviewsContainer = None,
    ) -> TaskListContainer:
        """Review multiple tasks to approve or decline the submitted work.

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

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

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

    @cast_models
    def create_task_review_by_id(
        self,
        contract_id: str,
        task_id: str,
        request_body: RequestBodyToCreatePgoTaskReviewsByIdReviewsContainer = None,
    ) -> TaskListContainer:
        """Review a single task to approve or decline the submitted work.

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

        Validator(
            RequestBodyToCreatePgoTaskReviewsByIdReviewsContainer
        ).is_optional().validate(request_body)
        Validator(str).validate(contract_id)
        Validator(str).validate(task_id)

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

        response = self.send_request(serialized_request)

        return TaskListContainer._unmap(response)

    @cast_models
    def delete_contract_pgo_tak(
        self, contract_id: str, task_id: str, reason: str = None
    ) -> GenericResultDeleted:
        """Delete task from the contract.

        :param contract_id: Deel contract id.
        :type contract_id: str
        :param task_id: ID of task entity.
        :type task_id: str
        :param reason: Reason for deleting an existing task, defaults to None
        :type reason: str, optional
        ...
        :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(task_id)
        Validator(str).is_optional().validate(reason)

        serialized_request = (
            Serializer(
                f"{self.base_url}/contracts/{{contract_id}}/tasks/{{task_id}}",
                self.get_default_headers(),
            )
            .add_path("contract_id", contract_id)
            .add_path("task_id", task_id)
            .add_query("reason", reason)
            .serialize()
            .set_method("DELETE")
        )

        response = self.send_request(serialized_request)

        return GenericResultDeleted._unmap(response)
