# 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.upload_employee_compliance_document_file_container import (
    UploadEmployeeComplianceDocumentFileContainer,
)
from ..models.upload_employee_compliance_document_container import (
    UploadEmployeeComplianceDocumentContainer,
)
from ..models.request_custom_verification_letter_container import (
    RequestCustomVerificationLetterContainer,
)
from ..models.hr_verification_letters_and_documents_list_container import (
    HrVerificationLettersAndDocumentsListContainer,
)
from ..models.get_employee_compliance_documents_container import (
    GetEmployeeComplianceDocumentsContainer,
)
from ..models.get_employee_compliance_document_template_download_link_container import (
    GetEmployeeComplianceDocumentTemplateDownloadLinkContainer,
)
from ..models.generic_result_updated import GenericResultUpdated
from ..models.generic_result_created import GenericResultCreated
from ..models.employee_tax_documents_list_container import (
    EmployeeTaxDocumentsListContainer,
)
from ..models.employee_payslips_list_container import EmployeePayslipsListContainer
from ..models.employee_contract_signature_to_create_container import (
    EmployeeContractSignatureToCreateContainer,
)
from ..models.employee_agreement_download_container import (
    EmployeeAgreementDownloadContainer,
)
from ..models.bank_account_to_add_container import BankAccountToAddContainer
from ..models.bank_account_guide_container import BankAccountGuideContainer
from ..models.bank_account_added_container import BankAccountAddedContainer
from ..models.additional_eor_info_container import AdditionalEorInfoContainer


class PartnerManagedService(BaseService):

    @cast_models
    def add_employee_additional_information(
        self,
        request_body: AdditionalEorInfoContainer,
        employee_id: str,
        contract_id: str,
    ) -> GenericResultUpdated:
        """Add additional information for an EOR employee.

        :param request_body: The request body.
        :type request_body: AdditionalEorInfoContainer
        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :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: GenericResultUpdated
        """

        Validator(AdditionalEorInfoContainer).validate(request_body)
        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/additional-information",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("POST")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return GenericResultUpdated._unmap(response)

    @cast_models
    def sign_employee_contract(
        self,
        request_body: EmployeeContractSignatureToCreateContainer,
        employee_id: str,
        contract_id: str,
    ) -> GenericResultCreated:
        """Sign a contract as a employee.

        :param request_body: The request body.
        :type request_body: EmployeeContractSignatureToCreateContainer
        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :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(EmployeeContractSignatureToCreateContainer).validate(request_body)
        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/signatures",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .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 request_custom_verification_letter(
        self,
        request_body: RequestCustomVerificationLetterContainer,
        employee_id: str,
        contract_id: str,
    ) -> GenericResultCreated:
        """Request employment verification letters, visa support, bank verification and more.

        :param request_body: The request body.
        :type request_body: RequestCustomVerificationLetterContainer
        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :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(RequestCustomVerificationLetterContainer).validate(request_body)
        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/custom-verification-letter",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .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_hr_verification_letters_and_documents(
        self, employee_id: str, contract_id: str
    ) -> HrVerificationLettersAndDocumentsListContainer:
        """List all HR verification letters and documents available.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :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: HrVerificationLettersAndDocumentsListContainer
        """

        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/hr-documents",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return HrVerificationLettersAndDocumentsListContainer._unmap(response)

    @cast_models
    def download_hr_verification_letters_and_documents(
        self, employee_id: str, contract_id: str, document_id: float
    ) -> EmployeeAgreementDownloadContainer:
        """Retrieve URL to download HR verification letters and documents.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :param contract_id: Deel contract id.
        :type contract_id: str
        :param document_id: Unique identifier for a compliance document in Deel.
        :type document_id: float
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: EmployeeAgreementDownloadContainer
        """

        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)
        Validator(float).validate(document_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/hr-documents/{{document_id}}/download",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("contract_id", contract_id)
            .add_path("document_id", document_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return EmployeeAgreementDownloadContainer._unmap(response)

    @cast_models
    def get_offer_letter_preview(self, employee_id: str, contract_id: str) -> str:
        """Retrieve an EOR job offer letter in HTML. This endpoint does not support IC and Global Payroll contract types.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :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: str
        """

        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/offer-letter",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return response

    @cast_models
    def get_employee_agreement_preview(self, employee_id: str, contract_id: str) -> str:
        """Retrieve an EOR Employee Agreement content in HTML.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :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: str
        """

        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/employee-agreement",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return response

    @cast_models
    def get_employee_agreement_download_link(
        self, employee_id: str, contract_id: str
    ) -> EmployeeAgreementDownloadContainer:
        """Get link to download the employee agreement PDF.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :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: EmployeeAgreementDownloadContainer
        """

        Validator(str).validate(employee_id)
        Validator(str).validate(contract_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/contracts/{{contract_id}}/employee-agreement/download",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("contract_id", contract_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return EmployeeAgreementDownloadContainer._unmap(response)

    @cast_models
    def get_bank_account_guide(self, employee_id: str) -> BankAccountGuideContainer:
        """Retrieve bank account form guide for an EOR employee. This data can be used to add a new bank account for an employee.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: BankAccountGuideContainer
        """

        Validator(str).validate(employee_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/banks/guide",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return BankAccountGuideContainer._unmap(response)

    @cast_models
    def add_bank_account(
        self, request_body: BankAccountToAddContainer, employee_id: str
    ) -> BankAccountAddedContainer:
        """Add bank account for an EOR employee.

        :param request_body: The request body.
        :type request_body: BankAccountToAddContainer
        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: BankAccountAddedContainer
        """

        Validator(BankAccountToAddContainer).validate(request_body)
        Validator(str).validate(employee_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/banks",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .serialize()
            .set_method("POST")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return BankAccountAddedContainer._unmap(response)

    @cast_models
    def patch_bank_account(
        self, request_body: BankAccountToAddContainer, employee_id: str, bank_id: str
    ) -> BankAccountAddedContainer:
        """Modify bank account for an EOR employee.

        :param request_body: The request body.
        :type request_body: BankAccountToAddContainer
        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :param bank_id: Bank Account id.
        :type bank_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: BankAccountAddedContainer
        """

        Validator(BankAccountToAddContainer).validate(request_body)
        Validator(str).validate(employee_id)
        Validator(str).validate(bank_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/banks/{{bank_id}}",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("bank_id", bank_id)
            .serialize()
            .set_method("PATCH")
            .set_body(request_body)
        )

        response = self.send_request(serialized_request)

        return BankAccountAddedContainer._unmap(response)

    @cast_models
    def get_employee_payslips(self, employee_id: str) -> EmployeePayslipsListContainer:
        """Get list of payslips for an EOR employee.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: EmployeePayslipsListContainer
        """

        Validator(str).validate(employee_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/payslips",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return EmployeePayslipsListContainer._unmap(response)

    @cast_models
    def get_employee_compliance_documents(
        self, employee_id: str
    ) -> GetEmployeeComplianceDocumentsContainer:
        """Get a list of employee compliance documents.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GetEmployeeComplianceDocumentsContainer
        """

        Validator(str).validate(employee_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/compliance-documents",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return GetEmployeeComplianceDocumentsContainer._unmap(response)

    @cast_models
    def upload_employee_compliance_document(
        self, request_body: dict, employee_id: str, document_id: float
    ) -> UploadEmployeeComplianceDocumentContainer:
        """Upload an employee compliance document.

        :param request_body: The request body.
        :type request_body: dict
        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :param document_id: Unique identifier for a compliance document in Deel.
        :type document_id: float
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: UploadEmployeeComplianceDocumentContainer
        """

        Validator(dict).validate(request_body)
        Validator(str).validate(employee_id)
        Validator(float).validate(document_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/compliance-documents/{{document_id}}",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("document_id", document_id)
            .serialize()
            .set_method("POST")
            .set_body(request_body, "multipart/form-data")
        )

        response = self.send_request(serialized_request)

        return UploadEmployeeComplianceDocumentContainer._unmap(response)

    @cast_models
    def get_employee_compliance_document_template(
        self, employee_id: str, document_id: float
    ) -> GetEmployeeComplianceDocumentTemplateDownloadLinkContainer:
        """Get the download link for an employee compliance document template, if it exists.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        :param document_id: Unique identifier for a compliance document in Deel.
        :type document_id: float
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: GetEmployeeComplianceDocumentTemplateDownloadLinkContainer
        """

        Validator(str).validate(employee_id)
        Validator(float).validate(document_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/compliance-documents/{{document_id}}/templates/download",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .add_path("document_id", document_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return GetEmployeeComplianceDocumentTemplateDownloadLinkContainer._unmap(
            response
        )

    @cast_models
    def get_employee_tax_documents(
        self, employee_id: str
    ) -> EmployeeTaxDocumentsListContainer:
        """Get list of tax documents for an employee.

        :param employee_id: Unique identifier for an employee in Deel.
        :type employee_id: str
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: Successful operation.
        :rtype: EmployeeTaxDocumentsListContainer
        """

        Validator(str).validate(employee_id)

        serialized_request = (
            Serializer(
                f"{self.base_url}/partner-managed/employees/{{employee_id}}/tax-documents",
                self.get_default_headers(),
            )
            .add_path("employee_id", employee_id)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return EmployeeTaxDocumentsListContainer._unmap(response)
