"""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.failure_category import (
    FailureCategory,
)
from cellpointapi.models.failure_module import (
    FailureModule,
)
from cellpointapi.models.non_negative_amount import (
    NonNegativeAmount,
)


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

    Details about a failure that happened on a transaction.

    Attributes:
        module (FailureModule): Which business module the failure happened in.
            <table>   <thead>     <tr>       <th>Module</th>
            <th>Description</th>     </tr>   </thead>   <tbody>     <tr>
            <td>PRE_AUTHORIZATION</td>       <td>Failure happened during
            pre-authorization checks.</td>     </tr>     <tr>
            <td>PAYMENT_PROCESSOR</td>       <td>Failure happened when processing the
            payment.</td>                               </tr>     <tr>
            <td>FOREIGN_EXCHANGE</td>       <td>Failure happened in foreign exchange
            (FX).</td>     </tr>     <tr>       <td>THREE_D_SECURE</td>
            <td>Failure happened during 3DSecure flow.</td>     </tr>     <tr>
            <td>FRAUD</td>       <td>Failure happened in fraud checks.</td>     </tr>
            </tbody> </table>
        category (FailureCategory): Category of transaction failure.  <table>
            <thead>     <tr>       <th>Category</th>       <th>Description</th>
            </tr>   </thead>   <tbody>     <tr>       <td>USER_ERROR</td>
            <td>The buyer has entered invalid details during the payment
            session.</td>     </tr>     <tr>       <td>INTEGRATION_ERROR</td>
            <td>There is an error with the integration between us and an external
            system for this request. Example - provider does not support decimal. Or
            MID does not exist.</td>     </tr>     <tr>       <td>SECURITY_ERROR</td>
            <td>         Payment failed to pass additional security screening
            verification.         EXAMPLES:           - CARD_BLOCKED           -
            AVS_FAILED           - FRAUD_SUSPICION           - 3DS_FAILED       </td>
            </tr>     <tr>       <td>TECHNICAL_ERROR</td>       <td>Transient errors
            that are happening due to unavailable of some system (possibly
            downstream).</td>     </tr>     <tr>       <td>TRANSACTION_ERROR</td>
            <td>Transaction related errors.</td>     </tr>   </tbody> </table>
        reason (str): Exact reason for the failure.  Examples:   -
            INVALID_CARD_NUMBER   - CARD_BLOCKED   - AVS_FAILED   - FRAUD_SUSPICION
            - 3DS_FAILED   - INVALID_MID   - CONNECTION_TIMEOUT
        description (str): Human readable reason for the failure.
        attempted_amount (NonNegativeAmount): Amount that was attempted.
        additional_properties (Dict[str, Any]): The additional properties for the
            model.

    """

    # Create a mapping from Model property names to API property names
    _names = {
        "module": "module",
        "category": "category",
        "reason": "reason",
        "description": "description",
        "attempted_amount": "attemptedAmount",
    }

    _optionals = [
        "attempted_amount",
    ]

    def __init__(
        self,
        module=None,
        category=None,
        reason=None,
        description=None,
        attempted_amount=APIHelper.SKIP,
        additional_properties=None):
        """Initialize a TransactionFailure instance."""
        # Initialize members of the class
        self.module = module
        self.category = category
        self.reason = reason
        self.description = description
        if attempted_amount is not APIHelper.SKIP:
            self.attempted_amount = attempted_amount

        # 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.

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

        # Extract variables from the dictionary
        module =\
            dictionary.get("module")\
            if dictionary.get("module")\
                else None
        category =\
            dictionary.get("category")\
            if dictionary.get("category")\
                else None
        reason =\
            dictionary.get("reason")\
            if dictionary.get("reason")\
                else None
        description =\
            dictionary.get("description")\
            if dictionary.get("description")\
                else None
        attempted_amount =\
            NonNegativeAmount.from_dictionary(
                dictionary.get("attemptedAmount"))\
                if "attemptedAmount" in dictionary.keys()\
                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(module,
                   category,
                   reason,
                   description,
                   attempted_amount,
                   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.

        """
        if isinstance(dictionary, cls):
            return APIHelper.is_valid_type(
                    value=dictionary.module,
                    type_callable=lambda value:
                        FailureModule.validate(value)) \
                and APIHelper.is_valid_type(
                    value=dictionary.category,
                    type_callable=lambda value:
                        FailureCategory.validate(value)) \
                and APIHelper.is_valid_type(
                    value=dictionary.reason,
                    type_callable=lambda value:
                        isinstance(
                        value,
                        str,
                )) \
                and APIHelper.is_valid_type(
                    value=dictionary.description,
                    type_callable=lambda value:
                        isinstance(
                        value,
                        str,
                ))

        if not isinstance(dictionary, dict):
            return False

        return APIHelper.is_valid_type(
                value=dictionary.get("module"),
                type_callable=lambda value:
                    FailureModule.validate(value)) \
            and APIHelper.is_valid_type(
                value=dictionary.get("category"),
                type_callable=lambda value:
                    FailureCategory.validate(value)) \
            and APIHelper.is_valid_type(
                value=dictionary.get("reason"),
                type_callable=lambda value:
                    isinstance(
                    value,
                    str,
            )) \
            and APIHelper.is_valid_type(
                value=dictionary.get("description"),
                type_callable=lambda value:
                    isinstance(
                    value,
                    str,
            ))

    def __repr__(self):
        """Return a unambiguous string representation."""
        _module=self.module
        _category=self.category
        _reason=self.reason
        _description=self.description
        _attempted_amount=(
            self.attempted_amount
            if hasattr(self, "attempted_amount")
            else None
        )
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"module={_module!r}, "
            f"category={_category!r}, "
            f"reason={_reason!r}, "
            f"description={_description!r}, "
            f"attempted_amount={_attempted_amount!r}, "
            f"additional_properties={_additional_properties!r}, "
            f")"
        )

    def __str__(self):
        """Return a human-readable string representation."""
        _module=self.module
        _category=self.category
        _reason=self.reason
        _description=self.description
        _attempted_amount=(
            self.attempted_amount
            if hasattr(self, "attempted_amount")
            else None
        )
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"module={_module!s}, "
            f"category={_category!s}, "
            f"reason={_reason!s}, "
            f"description={_description!s}, "
            f"attempted_amount={_attempted_amount!s}, "
            f"additional_properties={_additional_properties!s}, "
            f")"
        )
