# 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.update_worker_working_location_container import (
    UpdateWorkerWorkingLocationContainer,
)
from ..models.update_worker_department_container import UpdateWorkerDepartmentContainer
from ..models.timeoff_to_review_internal_container import (
    TimeoffToReviewInternalContainer,
)
from ..models.sort_dir_enum import SortDirEnum
from ..models.people_time_off_container import PeopleTimeOffContainer
from ..models.people_sort_by_enum import PeopleSortByEnum
from ..models.people_me import PeopleMe
from ..models.people_container import PeopleContainer
from ..models.people_by_id_container import PeopleByIdContainer
from ..models.internal_people_container import InternalPeopleContainer
from ..models.hris_direct_employee_container import HrisDirectEmployeeContainer
from ..models.hris_direct_employee import HrisDirectEmployee
from ..models.hiring_status_enum import HiringStatusEnum
from ..models.generic_result_updated import GenericResultUpdated
from ..models.generic_result_deleted import GenericResultDeleted
from ..models.employee_timeoffs_policies_container import (
    EmployeeTimeoffsPoliciesContainer,
)
from ..models.employee_timeoffs_entitlements_container import (
    EmployeeTimeoffsEntitlementsContainer,
)
from ..models.employee_timeoffs_creation_container import (
    EmployeeTimeoffsCreationContainer,
)
from ..models.employee_timeoffs_container import EmployeeTimeoffsContainer
from ..models.create_people_timeoff import CreatePeopleTimeoff


class PeopleService(BaseService):

    @cast_models
    def create_direct_employee(
        self, request_body: HrisDirectEmployee
    ) -> HrisDirectEmployeeContainer:
        """Create a new Hris direct employee.

        :param request_body: The request body.
        :type request_body: HrisDirectEmployee
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Hris direct employee object that was created or edited
        :rtype: HrisDirectEmployeeContainer
        """

        Validator(HrisDirectEmployee).validate(request_body)

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

        response = self.send_request(serialized_request)

        return HrisDirectEmployeeContainer._unmap(response)

    @cast_models
    def get_internal_people_list(
        self, offset: float = None, limit: float = None
    ) -> InternalPeopleContainer:
        """Retrieve a list of internal people in your organization.

        :param offset: Return a page of results with given number of records., defaults to None
        :type offset: float, optional
        :param limit: Return a page of results with given number of records., defaults to None
        :type limit: float, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: InternalPeopleContainer
        """

        Validator(float).is_optional().min(0).max(999999999).validate(offset)
        Validator(float).is_optional().min(1).max(200).validate(limit)

        serialized_request = (
            Serializer(f"{self.base_url}/internal/people", self.get_default_headers())
            .add_query("offset", offset)
            .add_query("limit", limit)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return InternalPeopleContainer._unmap(response)

    @cast_models
    def get_people_list(
        self,
        offset: float = None,
        limit: float = None,
        search: str = None,
        sort_by: PeopleSortByEnum = None,
        sort_order: SortDirEnum = None,
        hiring_statuses: HiringStatusEnum = None,
    ) -> PeopleContainer:
        """Retrieve a list of People in your organization.

        :param offset: Return a page of results with given number of records., defaults to None
        :type offset: float, optional
        :param limit: Return a page of results with given number of records., defaults to None
        :type limit: float, optional
        :param search: Include a contract if by name or contractor name contains given search term., defaults to None
        :type search: str, optional
        :param sort_by: Sort people by given field name., defaults to None
        :type sort_by: PeopleSortByEnum, optional
        :param sort_order: Order direction of results; ascending or descending., defaults to None
        :type sort_order: SortDirEnum, optional
        :param hiring_statuses: Employee's current hiring status., defaults to None
        :type hiring_statuses: HiringStatusEnum, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: PeopleContainer
        """

        Validator(float).is_optional().min(0).max(999999999).validate(offset)
        Validator(float).is_optional().min(1).max(200).validate(limit)
        Validator(str).is_optional().validate(search)
        Validator(PeopleSortByEnum).is_optional().validate(sort_by)
        Validator(SortDirEnum).is_optional().validate(sort_order)
        Validator(HiringStatusEnum).is_optional().validate(hiring_statuses)

        serialized_request = (
            Serializer(f"{self.base_url}/people", self.get_default_headers())
            .add_query("offset", offset)
            .add_query("limit", limit)
            .add_query("search", search)
            .add_query("sort_by", sort_by)
            .add_query("sort_order", sort_order)
            .add_query("hiring_statuses[]", hiring_statuses)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return PeopleContainer._unmap(response)

    @cast_models
    def get_people_by_id(self, worker_id: str) -> PeopleByIdContainer:
        """Retrieve a single person in your organization.

        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: PeopleByIdContainer
        """

        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return PeopleByIdContainer._unmap(response)

    @cast_models
    def update_people_department(
        self, worker_id: str, request_body: UpdateWorkerDepartmentContainer = None
    ) -> GenericResultUpdated:
        """Update worker department.

        :param request_body: The request body., defaults to None
        :type request_body: UpdateWorkerDepartmentContainer, optional
        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GenericResultUpdated
        """

        Validator(UpdateWorkerDepartmentContainer).is_optional().validate(request_body)
        Validator(str).validate(worker_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/people/{{worker_id}}/department",
                self.get_default_headers(),
            )
            .add_path("worker_id", worker_id)
            .serialize()
            .set_method("PUT")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return GenericResultUpdated._unmap(response)

    @cast_models
    def update_people_working_location(
        self, worker_id: str, request_body: UpdateWorkerWorkingLocationContainer = None
    ) -> GenericResultUpdated:
        """Update worker working location.

        :param request_body: The request body., defaults to None
        :type request_body: UpdateWorkerWorkingLocationContainer, optional
        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GenericResultUpdated
        """

        Validator(UpdateWorkerWorkingLocationContainer).is_optional().validate(
            request_body
        )
        Validator(str).validate(worker_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/people/{{worker_id}}/working-location",
                self.get_default_headers(),
            )
            .add_path("worker_id", worker_id)
            .serialize()
            .set_method("PUT")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return GenericResultUpdated._unmap(response)

    @cast_models
    def get_people(self) -> PeopleMe:
        """Retrieve the current user's profile.

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

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

        response = self.send_request(serialized_request)

        return PeopleMe._unmap(response)

    @cast_models
    def get_time_offs_for_employee(self, worker_id: str) -> EmployeeTimeoffsContainer:
        """List of time offs by worker id. Worker id can be retreived using /people endpoint.

        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: successful operation
        :rtype: EmployeeTimeoffsContainer
        """

        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return EmployeeTimeoffsContainer._unmap(response)

    @cast_models
    def create_time_offs_for_employee(
        self, worker_id: str, request_body: dict = None
    ) -> EmployeeTimeoffsCreationContainer:
        """Add a time off request for a worker. New requests are auto-approved.

        :param request_body: The request body., defaults to None
        :type request_body: dict, optional
        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: successful operation
        :rtype: EmployeeTimeoffsCreationContainer
        """

        Validator(dict).is_optional().validate(request_body)
        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return EmployeeTimeoffsCreationContainer._unmap(response)

    @cast_models
    def get_time_offs_entitlements_for_employee(
        self, worker_id: str
    ) -> EmployeeTimeoffsEntitlementsContainer:
        """Retrieve a list of time off entitlements for a worker.

        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: successful operation
        :rtype: EmployeeTimeoffsEntitlementsContainer
        """

        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return EmployeeTimeoffsEntitlementsContainer._unmap(response)

    @cast_models
    def update_time_offs_for_employee(
        self, timeoff_id: str, worker_id: str, request_body: dict = None
    ) -> EmployeeTimeoffsCreationContainer:
        """Edit a time off request for a worker.

        :param request_body: The request body., defaults to None
        :type request_body: dict, optional
        :param timeoff_id: Unique identifier for a time-off in Deel.
        :type timeoff_id: str
        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: successful operation
        :rtype: EmployeeTimeoffsCreationContainer
        """

        Validator(dict).is_optional().validate(request_body)
        Validator(str).validate(timeoff_id)
        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return EmployeeTimeoffsCreationContainer._unmap(response)

    @cast_models
    def delete_time_offs_for_employee(
        self, timeoff_id: str, worker_id: str
    ) -> GenericResultDeleted:
        """Delete a time off request.

        :param timeoff_id: Unique identifier for a time-off in Deel.
        :type timeoff_id: str
        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GenericResultDeleted
        """

        Validator(str).validate(timeoff_id)
        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return GenericResultDeleted._unmap(response)

    @cast_models
    def review_time_offs_for_employee(
        self,
        request_body: TimeoffToReviewInternalContainer,
        timeoff_id: str,
        worker_id: str,
    ) -> EmployeeTimeoffsContainer:
        """Approve or decline a time off request. New requests are auto-approved. Hence they don't need to be manually approved.

        :param request_body: The request body.
        :type request_body: TimeoffToReviewInternalContainer
        :param timeoff_id: Unique identifier for a time-off in Deel.
        :type timeoff_id: str
        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: successful operation
        :rtype: EmployeeTimeoffsContainer
        """

        Validator(TimeoffToReviewInternalContainer).validate(request_body)
        Validator(str).validate(timeoff_id)
        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return EmployeeTimeoffsContainer._unmap(response)

    @cast_models
    def get_time_offs_policies_for_employee(
        self, worker_id: str
    ) -> EmployeeTimeoffsPoliciesContainer:
        """Retrieve a list of time off policies for a worker.

        :param worker_id: Unique identifier for a worker.
        :type worker_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: successful operation
        :rtype: EmployeeTimeoffsPoliciesContainer
        """

        Validator(str).validate(worker_id)

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

        response = self.send_request(serialized_request)

        return EmployeeTimeoffsPoliciesContainer._unmap(response)
