"""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.payment_processor import (
    PaymentProcessor,
)
from cellpointapi.models.refund_method import (
    RefundMethod,
)
from cellpointapi.models.refund_reason import (
    RefundReason,
)
from cellpointapi.models.refund_status import (
    RefundStatus,
)
from cellpointapi.models.refund_transaction_amount import (
    RefundTransactionAmount,
)
from cellpointapi.models.refund_type import (
    RefundType,
)
from cellpointapi.models.related_payment import (
    RelatedPayment,
)
from cellpointapi.models.transaction_failure import (
    TransactionFailure,
)
from cellpointapi.models.type_2 import Type2


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

    A refund item.

    Attributes:
        id (str): Unique identifier for this transaction.
        order_id (str): Identifier for an order.
        mtype (Type2): Discriminator used to identify the type of transaction.
        failure (TransactionFailure): Details about a failure that happened on a
            transaction.
        created_at (datetime): When the transaction was created.
        payment_processor (PaymentProcessor): Acquirer or Payment Service Provider
            (PSP) that processed the payment.
        reason (RefundReason): Optional merchant-defined reason for the refund.
        status (RefundStatus): Status of the refund.
        processed_at (datetime): When the refund was last processed. A refund can be
            processed multiple times if it fails initially. Note: this is different
            from `refundedAt` which is when the refund was successfully completed,
            whereas `processedAt` is when refund processing started.
        refunded_at (datetime): When the refund was successfully completed.
        refund_type (RefundType): Type of refund to do, either partial or full. The
            actual refund however can be for any amount regardless of this type. The
            reason being that there may be fees so the refund can be full even though
            some amount is kept.
        refund_method (RefundMethod): Method of refunding the payment.
        amount (RefundTransactionAmount): Amount that was attempted.
        original_payment_transactions (List[RelatedPayment]): Payment transaction(s)
            that are being refunded.  This will often only be a single transaction,
            but there are situations depending on merchant configuration where a
            single refund will be against multiple payments.
        refunding_payment_instrument (CardPaymentInstrument |
            ApplePayPaymentInstrument | PayPalPaymentInstrument |
            VoucherPaymentInstrument | WalletPaymentInstrument |
            UpliftPaymentInstrument): The payment instrument that is being used in
            the transaction.
        additional_properties (Dict[str, Any]): The additional properties for the
            model.

    """

    # Create a mapping from Model property names to API property names
    _names = {
        "id": "id",
        "mtype": "type",
        "status": "status",
        "refund_type": "refundType",
        "refund_method": "refundMethod",
        "amount": "amount",
        "original_payment_transactions": "originalPaymentTransactions",
        "refunding_payment_instrument": "refundingPaymentInstrument",
        "order_id": "orderId",
        "failure": "failure",
        "created_at": "createdAt",
        "payment_processor": "paymentProcessor",
        "reason": "reason",
        "processed_at": "processedAt",
        "refunded_at": "refundedAt",
    }

    _optionals = [
        "order_id",
        "failure",
        "created_at",
        "payment_processor",
        "reason",
        "processed_at",
        "refunded_at",
    ]

    def __init__(
        self,
        id=None,
        mtype=None,
        status=None,
        refund_type=None,
        refund_method=None,
        amount=None,
        original_payment_transactions=None,
        refunding_payment_instrument=None,
        order_id=APIHelper.SKIP,
        failure=APIHelper.SKIP,
        created_at=APIHelper.SKIP,
        payment_processor=APIHelper.SKIP,
        reason=APIHelper.SKIP,
        processed_at=APIHelper.SKIP,
        refunded_at=APIHelper.SKIP,
        additional_properties=None):
        """Initialize a RefundItem instance."""
        # Initialize members of the class
        self.id = id
        if order_id is not APIHelper.SKIP:
            self.order_id = order_id
        self.mtype = mtype
        if failure is not APIHelper.SKIP:
            self.failure = failure
        if created_at is not APIHelper.SKIP:
            self.created_at =\
                 APIHelper.apply_datetime_converter(
                created_at, APIHelper.RFC3339DateTime)\
                 if created_at else None
        if payment_processor is not APIHelper.SKIP:
            self.payment_processor = payment_processor
        if reason is not APIHelper.SKIP:
            self.reason = reason
        self.status = status
        if processed_at is not APIHelper.SKIP:
            self.processed_at =\
                 APIHelper.apply_datetime_converter(
                processed_at, APIHelper.RFC3339DateTime)\
                 if processed_at else None
        if refunded_at is not APIHelper.SKIP:
            self.refunded_at =\
                 APIHelper.apply_datetime_converter(
                refunded_at, APIHelper.RFC3339DateTime)\
                 if refunded_at else None
        self.refund_type = refund_type
        self.refund_method = refund_method
        self.amount = amount
        self.original_payment_transactions = original_payment_transactions
        self.refunding_payment_instrument = refunding_payment_instrument

        # 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
        id =\
            dictionary.get("id")\
            if dictionary.get("id")\
                else None
        mtype =\
            dictionary.get("type")\
            if dictionary.get("type")\
                else None
        status =\
            dictionary.get("status")\
            if dictionary.get("status")\
                else None
        refund_type =\
            dictionary.get("refundType")\
            if dictionary.get("refundType")\
                else None
        refund_method =\
            dictionary.get("refundMethod")\
            if dictionary.get("refundMethod")\
                else None
        amount =\
            RefundTransactionAmount.from_dictionary(
                dictionary.get("amount"))\
                if dictionary.get("amount") else None
        original_payment_transactions = None
        if dictionary.get("originalPaymentTransactions") is not None:
            original_payment_transactions = [
                RelatedPayment.from_dictionary(x)
                    for x in dictionary.get("originalPaymentTransactions")
            ]
        refunding_payment_instrument = APIHelper.deserialize_union_type(
            UnionTypeLookUp.get("PaymentInstrument"),
            dictionary.get("refundingPaymentInstrument"),
            False)\
            if dictionary.get("refundingPaymentInstrument") is not None\
            else None
        order_id =\
            dictionary.get("orderId")\
            if dictionary.get("orderId")\
                else APIHelper.SKIP
        failure =\
            TransactionFailure.from_dictionary(
                dictionary.get("failure"))\
                if "failure" in dictionary.keys()\
                else APIHelper.SKIP
        created_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("createdAt")).datetime\
            if dictionary.get("createdAt") else APIHelper.SKIP
        payment_processor =\
            PaymentProcessor.from_dictionary(
                dictionary.get("paymentProcessor"))\
                if "paymentProcessor" in dictionary.keys()\
                else APIHelper.SKIP
        reason =\
            RefundReason.from_dictionary(
                dictionary.get("reason"))\
                if "reason" in dictionary.keys()\
                else APIHelper.SKIP
        processed_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("processedAt")).datetime\
            if dictionary.get("processedAt") else APIHelper.SKIP
        refunded_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("refundedAt")).datetime\
            if dictionary.get("refundedAt") 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(id,
                   mtype,
                   status,
                   refund_type,
                   refund_method,
                   amount,
                   original_payment_transactions,
                   refunding_payment_instrument,
                   order_id,
                   failure,
                   created_at,
                   payment_processor,
                   reason,
                   processed_at,
                   refunded_at,
                   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 APIHelper.is_valid_type(
                    value=dictionary.id,
                    type_callable=lambda value:
                        isinstance(
                        value,
                        str,
                )) \
                and APIHelper.is_valid_type(
                    value=dictionary.mtype,
                    type_callable=lambda value:
                        Type2.validate(value)) \
                and APIHelper.is_valid_type(
                    value=dictionary.status,
                    type_callable=lambda value:
                        RefundStatus.validate(value)) \
                and APIHelper.is_valid_type(
                    value=dictionary.refund_type,
                    type_callable=lambda value:
                        RefundType.validate(value)) \
                and APIHelper.is_valid_type(
                    value=dictionary.refund_method,
                    type_callable=lambda value:
                        RefundMethod.validate(value)) \
                and APIHelper.is_valid_type(
                    value=dictionary.amount,
                    type_callable=lambda value:
                        RefundTransactionAmount.validate(value),
                    is_model_dict=True) \
                and APIHelper.is_valid_type(
                    value=dictionary.original_payment_transactions,
                    type_callable=lambda value:
                        RelatedPayment.validate(value),
                    is_model_dict=True,
                    is_inner_model_dict=True) \
                and (UnionTypeLookUp.get("PaymentInstrument")
                .validate(dictionary.refunding_payment_instrument).is_valid)

        if not isinstance(dictionary, dict):
            return False

        return APIHelper.is_valid_type(
                value=dictionary.get("id"),
                type_callable=lambda value:
                    isinstance(
                    value,
                    str,
            )) \
            and APIHelper.is_valid_type(
                value=dictionary.get("type"),
                type_callable=lambda value:
                    Type2.validate(value)) \
            and APIHelper.is_valid_type(
                value=dictionary.get("status"),
                type_callable=lambda value:
                    RefundStatus.validate(value)) \
            and APIHelper.is_valid_type(
                value=dictionary.get("refundType"),
                type_callable=lambda value:
                    RefundType.validate(value)) \
            and APIHelper.is_valid_type(
                value=dictionary.get("refundMethod"),
                type_callable=lambda value:
                    RefundMethod.validate(value)) \
            and APIHelper.is_valid_type(
                value=dictionary.get("amount"),
                type_callable=lambda value:
                    RefundTransactionAmount.validate(value),
                is_model_dict=True) \
            and APIHelper.is_valid_type(
                value=dictionary.get("originalPaymentTransactions"),
                type_callable=lambda value:
                    RelatedPayment.validate(value),
                is_model_dict=True,
                is_inner_model_dict=True) \
            and (UnionTypeLookUp.get("PaymentInstrument")
            .validate(dictionary.get("refundingPaymentInstrument")).is_valid)

    def __repr__(self):
        """Return a unambiguous string representation."""
        _id=self.id
        _order_id=(
            self.order_id
            if hasattr(self, "order_id")
            else None
        )
        _mtype=self.mtype
        _failure=(
            self.failure
            if hasattr(self, "failure")
            else None
        )
        _created_at=(
            self.created_at
            if hasattr(self, "created_at")
            else None
        )
        _payment_processor=(
            self.payment_processor
            if hasattr(self, "payment_processor")
            else None
        )
        _reason=(
            self.reason
            if hasattr(self, "reason")
            else None
        )
        _status=self.status
        _processed_at=(
            self.processed_at
            if hasattr(self, "processed_at")
            else None
        )
        _refunded_at=(
            self.refunded_at
            if hasattr(self, "refunded_at")
            else None
        )
        _refund_type=self.refund_type
        _refund_method=self.refund_method
        _amount=self.amount
        _original_payment_transactions=self.original_payment_transactions
        _refunding_payment_instrument=self.refunding_payment_instrument
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"id={_id!r}, "
            f"order_id={_order_id!r}, "
            f"mtype={_mtype!r}, "
            f"failure={_failure!r}, "
            f"created_at={_created_at!r}, "
            f"payment_processor={_payment_processor!r}, "
            f"reason={_reason!r}, "
            f"status={_status!r}, "
            f"processed_at={_processed_at!r}, "
            f"refunded_at={_refunded_at!r}, "
            f"refund_type={_refund_type!r}, "
            f"refund_method={_refund_method!r}, "
            f"amount={_amount!r}, "
            f"original_payment_transactions={_original_payment_transactions!r}, "
            f"refunding_payment_instrument={_refunding_payment_instrument!r}, "
            f"additional_properties={_additional_properties!r}, "
            f")"
        )

    def __str__(self):
        """Return a human-readable string representation."""
        _id=self.id
        _order_id=(
            self.order_id
            if hasattr(self, "order_id")
            else None
        )
        _mtype=self.mtype
        _failure=(
            self.failure
            if hasattr(self, "failure")
            else None
        )
        _created_at=(
            self.created_at
            if hasattr(self, "created_at")
            else None
        )
        _payment_processor=(
            self.payment_processor
            if hasattr(self, "payment_processor")
            else None
        )
        _reason=(
            self.reason
            if hasattr(self, "reason")
            else None
        )
        _status=self.status
        _processed_at=(
            self.processed_at
            if hasattr(self, "processed_at")
            else None
        )
        _refunded_at=(
            self.refunded_at
            if hasattr(self, "refunded_at")
            else None
        )
        _refund_type=self.refund_type
        _refund_method=self.refund_method
        _amount=self.amount
        _original_payment_transactions=self.original_payment_transactions
        _refunding_payment_instrument=self.refunding_payment_instrument
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"id={_id!s}, "
            f"order_id={_order_id!s}, "
            f"mtype={_mtype!s}, "
            f"failure={_failure!s}, "
            f"created_at={_created_at!s}, "
            f"payment_processor={_payment_processor!s}, "
            f"reason={_reason!s}, "
            f"status={_status!s}, "
            f"processed_at={_processed_at!s}, "
            f"refunded_at={_refunded_at!s}, "
            f"refund_type={_refund_type!s}, "
            f"refund_method={_refund_method!s}, "
            f"amount={_amount!s}, "
            f"original_payment_transactions={_original_payment_transactions!s}, "
            f"refunding_payment_instrument={_refunding_payment_instrument!s}, "
            f"additional_properties={_additional_properties!s}, "
            f")"
        )
