"""cellpointapi.

This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).
"""

# ruff: noqa: E501
from cellpointapi.api_helper import APIHelper
from cellpointapi.models.non_negative_amount import (
    NonNegativeAmount,
)


class Authorization(object):
    """Implementation of the 'Authorization' model.

    Contains the authorization request object.

    Attributes:
        payment_instrument (CardPaymentInstrument | ApplePayPaymentInstrument |
            PayPalPaymentInstrument | VoucherPaymentInstrument |
            WalletPaymentInstrument | UpliftPaymentInstrument): The payment
            instrument to be used for the authorization.
        amount (NonNegativeAmount): Amount to be authorized related to the order, if
            it's null, the order's total amount will be authorized, if it's bigger
            than the order's total amount, no authorization will happen
        has_accepted_terms_and_conditions (bool): Whether the Terms and Conditions
            have been accepted. Before the order can transition to a PAID state, the
            terms and conditions must be accepted. Each payment can mark itself as
            accepting those terms, but if the payments weren't marked so, an
            additional call to this `confirm-payments` operation in `Orders` would be
            required after all the payments have been made. The first payment to
            accept the terms and conditions accepts it for all further payments for
            the same order. Further requests to accept the terms and conditions do
            nothing.
        custom (Dict[str, str]): Custom data to attach to the authorization for
            tracking and analytical reasons by a merchant.  > Note: These properties
            are not used by CellPoint Digital for any payment processing and will not
            be passed to any acquirers.
        additional_properties (Dict[str, Any]): The additional properties for the
            model.

    """

    # Create a mapping from Model property names to API property names
    _names = {
        "payment_instrument": "paymentInstrument",
        "has_accepted_terms_and_conditions": "hasAcceptedTermsAndConditions",
        "amount": "amount",
        "custom": "custom",
    }

    _optionals = [
        "amount",
        "custom",
    ]

    def __init__(
        self,
        payment_instrument=None,
        has_accepted_terms_and_conditions=None,
        amount=APIHelper.SKIP,
        custom=APIHelper.SKIP,
        additional_properties=None):
        """Initialize a Authorization instance."""
        # Initialize members of the class
        self.payment_instrument = payment_instrument
        if amount is not APIHelper.SKIP:
            self.amount = amount
        self.has_accepted_terms_and_conditions = has_accepted_terms_and_conditions
        if custom is not APIHelper.SKIP:
            self.custom = custom

        # Add additional model properties to the instance
        if additional_properties is None:
            additional_properties = {}
        self.additional_properties = additional_properties

    @classmethod
    def from_dictionary(cls,
                        dictionary):
        """Create an instance of this model from a dictionary

        Args:
            dictionary (dictionary): A dictionary representation of the object
            as obtained from the deserialization of the server's response. The
            keys MUST match property names in the API description.

        Returns:
            object: An instance of this structure class.

        """
        from cellpointapi.utilities.union_type_lookup import (
            UnionTypeLookUp,
        )

        if not isinstance(dictionary, dict) or dictionary is None:
            return None

        # Extract variables from the dictionary
        payment_instrument = APIHelper.deserialize_union_type(
            UnionTypeLookUp.get("AuthorizationPaymentInstrument"),
            dictionary.get("paymentInstrument"),
            False)\
            if dictionary.get("paymentInstrument") is not None\
            else None
        has_accepted_terms_and_conditions =\
            dictionary.get("hasAcceptedTermsAndConditions")\
            if "hasAcceptedTermsAndConditions" in dictionary.keys()\
                else None
        amount =\
            NonNegativeAmount.from_dictionary(
                dictionary.get("amount"))\
                if "amount" in dictionary.keys()\
                else APIHelper.SKIP
        custom =\
            dictionary.get("custom")\
            if dictionary.get("custom")\
                else APIHelper.SKIP

        additional_properties = APIHelper.get_additional_properties(
            dictionary={k: v for k, v in dictionary.items()
                        if k not in cls._names.values()},
            unboxing_function=lambda value: value)

        # Return an object of this model
        return cls(payment_instrument,
                   has_accepted_terms_and_conditions,
                   amount,
                   custom,
                   additional_properties)

    @classmethod
    def validate(cls, dictionary):
        """Validate dictionary against class required properties

        Args:
            dictionary (dictionary): A dictionary representation of the object
            as obtained from the deserialization of the server's response. The
            keys MUST match property names in the API description.

        Returns:
            boolean : if dictionary is valid contains required properties.

        """
        from cellpointapi.utilities.union_type_lookup import (
            UnionTypeLookUp,
        )

        if isinstance(dictionary, cls):
            return (UnionTypeLookUp.get("AuthorizationPaymentInstrument")
                .validate(dictionary.payment_instrument).is_valid) \
                and APIHelper.is_valid_type(
                    value=dictionary.has_accepted_terms_and_conditions,
                    type_callable=lambda value:
                        isinstance(
                        value,
                        bool,
                ))

        if not isinstance(dictionary, dict):
            return False

        return (UnionTypeLookUp.get("AuthorizationPaymentInstrument")
            .validate(dictionary.get("paymentInstrument")).is_valid) \
            and APIHelper.is_valid_type(
                value=dictionary.get("hasAcceptedTermsAndConditions"),
                type_callable=lambda value:
                    isinstance(
                    value,
                    bool,
            ))

    def __repr__(self):
        """Return a unambiguous string representation."""
        _payment_instrument=self.payment_instrument
        _amount=(
            self.amount
            if hasattr(self, "amount")
            else None
        )
        _has_accepted_terms_and_conditions=self.has_accepted_terms_and_conditions
        _custom=(
            self.custom
            if hasattr(self, "custom")
            else None
        )
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"payment_instrument={_payment_instrument!r}, "
            f"amount={_amount!r}, "
            f"has_accepted_terms_and_conditions={_has_accepted_terms_and_conditions!r}, "
            f"custom={_custom!r}, "
            f"additional_properties={_additional_properties!r}, "
            f")"
        )

    def __str__(self):
        """Return a human-readable string representation."""
        _payment_instrument=self.payment_instrument
        _amount=(
            self.amount
            if hasattr(self, "amount")
            else None
        )
        _has_accepted_terms_and_conditions=self.has_accepted_terms_and_conditions
        _custom=(
            self.custom
            if hasattr(self, "custom")
            else None
        )
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"payment_instrument={_payment_instrument!s}, "
            f"amount={_amount!s}, "
            f"has_accepted_terms_and_conditions={_has_accepted_terms_and_conditions!s}, "
            f"custom={_custom!s}, "
            f"additional_properties={_additional_properties!s}, "
            f")"
        )
