# coding: utf-8

"""
    Synctera API

    <h2>Let's build something great.</h2><p>Welcome to the official reference documentation for Synctera APIs. Our APIs are the best way to automate your company's banking needs and are designed to be easy to understand and implement.</p><p>We're continuously growing this library and what you see here is just the start, but if you need something specific or have a question, <a class='text-blue-600' href='https://synctera.com/contact' target='_blank' rel='noreferrer'>contact us</a>.</p>  # noqa: E501

    The version of the OpenAPI document: 0.41.0
    Contact: dev@swadesh.co
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""


from __future__ import annotations
from inspect import getfullargspec
import pprint
import re  # noqa: F401
import json

from datetime import datetime
from typing import Dict, Optional
from pydantic import BaseModel, Field, StrictBool, StrictStr, constr, validator
from synctera_client_ng.models.card_brand import CardBrand
from synctera_client_ng.models.card_status import CardStatus
from synctera_client_ng.models.card_status_reason_code import CardStatusReasonCode
from synctera_client_ng.models.emboss_name import EmbossName

class VirtualCardResponse(BaseModel):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """
    form: StrictStr = ...
    account_id: StrictStr = Field(..., description="The ID of the account to which the card will be linked")
    card_product_id: StrictStr = Field(..., description="The card product to which the card is attached")
    creation_time: datetime = Field(..., description="The timestamp representing when the card issuance request was made")
    customer_id: StrictStr = Field(..., description="The ID of the customer to whom the card will be issued")
    emboss_name: EmbossName = ...
    expiration_month: StrictStr = ...
    expiration_time: Optional[datetime] = Field(None, description="The timestamp representing when the card would expire at")
    expiration_year: StrictStr = ...
    id: StrictStr = Field(..., description="Card ID")
    is_pin_set: Optional[StrictBool] = Field(False, description="indicates whether a pin has been set on the card")
    last_four: StrictStr = Field(..., description="The last 4 digits of the card PAN")
    last_modified_time: Optional[datetime] = Field(None, description="The timestamp representing when the card was last modified at")
    metadata: Optional[Dict[str, StrictStr]] = Field(None, description="Additional data to include in the request structured as key-value pairs")
    reissue_reason: Optional[StrictStr] = Field(None, description="This is the reason the card needs to be reissued, if any. The reason determines several behaviours:   - whether or not the new card will use the same PAN as the original card   - the old card will be terminated and if so, when it will be terminated  Reason                 | Same PAN | Terminate Old Card ---------------------- | -------- | ------------------ EXPIRATION             | yes      | on activation LOST                   | no       | immediately STOLEN                 | no       | immediately DAMAGED                | yes      | on activation VIRTUAL_TO_PHYSICAL(*) | yes      | on activation PRODUCT_CHANGE         | yes      | on activation NAME_CHANGE(**)        | yes      | on activation APPEARANCE             | yes      | on activation  (*) VIRTUAL_TO_PHYSICAL is deprecated. Please use PRODUCT_CHANGE whenever reissuing from one card product to another, including from a virtual product to a physical product.  (**) NAME_CHANGE is deprecated. Please use APPEARANCE whenever reissuing in order to change the appearance of a card, such as the printed name or custom image.  For all reasons, the new card will use the same PIN as the original card and digital wallet tokens will reassigned to the new card ")
    reissued_from_id: Optional[StrictStr] = Field(None, description="When reissuing a card, specify the card to be replaced here. When getting a card's details, if this card was issued as a reissuance of another card, this ID refers to the card was replaced. If this field is set, then reissue_reason must also be set. ")
    reissued_to_id: Optional[StrictStr] = Field(None, description="If this card was reissued, this ID refers to the card that replaced it.")
    type: StrictStr = Field(..., description="Indicates the type of card to be issued")
    card_status: CardStatus = ...
    memo: Optional[constr(strict=True, max_length=255)] = Field(None, description="Additional details about the reason for the status change")
    status_reason: CardStatusReasonCode = ...
    bin: Optional[StrictStr] = Field(None, description="The bin number")
    card_brand: CardBrand = ...
    __properties = ["form", "account_id", "card_product_id", "creation_time", "customer_id", "emboss_name", "expiration_month", "expiration_time", "expiration_year", "id", "is_pin_set", "last_four", "last_modified_time", "metadata", "reissue_reason", "reissued_from_id", "reissued_to_id", "type", "card_status", "memo", "status_reason", "bin", "card_brand"]

    @validator('form')
    def form_validate_enum(cls, v):
        if v not in ('VIRTUAL'):
            raise ValueError("must validate the enum values ('VIRTUAL')")
        return v

    @validator('reissue_reason')
    def reissue_reason_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ('EXPIRATION', 'LOST', 'STOLEN', 'DAMAGED', 'NAME_CHANGE', 'VIRTUAL_TO_PHYSICAL', 'PRODUCT_CHANGE', 'APPEARANCE'):
            raise ValueError("must validate the enum values ('EXPIRATION', 'LOST', 'STOLEN', 'DAMAGED', 'NAME_CHANGE', 'VIRTUAL_TO_PHYSICAL', 'PRODUCT_CHANGE', 'APPEARANCE')")
        return v

    @validator('type')
    def type_validate_enum(cls, v):
        if v not in ('DEBIT'):
            raise ValueError("must validate the enum values ('DEBIT')")
        return v

    class Config:
        allow_population_by_field_name = True
        validate_assignment = True

    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.dict(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> VirtualCardResponse:
        """Create an instance of VirtualCardResponse from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        _dict = self.dict(by_alias=True,
                          exclude={
                            "creation_time",
                            "expiration_month",
                            "expiration_time",
                            "expiration_year",
                            "id",
                            "is_pin_set",
                            "last_four",
                            "last_modified_time",
                            "reissued_to_id",
                          },
                          exclude_none=True)
        # override the default output from pydantic by calling `to_dict()` of emboss_name
        if self.emboss_name:
            _dict['emboss_name'] = self.emboss_name.to_dict()
        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> VirtualCardResponse:
        """Create an instance of VirtualCardResponse from a dict"""
        if obj is None:
            return None

        if type(obj) is not dict:
            return VirtualCardResponse.parse_obj(obj)

        _obj = VirtualCardResponse.parse_obj({
            "form": obj.get("form"),
            "account_id": obj.get("account_id"),
            "card_product_id": obj.get("card_product_id"),
            "creation_time": obj.get("creation_time"),
            "customer_id": obj.get("customer_id"),
            "emboss_name": EmbossName.from_dict(obj.get("emboss_name")) if obj.get("emboss_name") is not None else None,
            "expiration_month": obj.get("expiration_month"),
            "expiration_time": obj.get("expiration_time"),
            "expiration_year": obj.get("expiration_year"),
            "id": obj.get("id"),
            "is_pin_set": obj.get("is_pin_set") if obj.get("is_pin_set") is not None else False,
            "last_four": obj.get("last_four"),
            "last_modified_time": obj.get("last_modified_time"),
            "metadata": obj.get("metadata"),
            "reissue_reason": obj.get("reissue_reason"),
            "reissued_from_id": obj.get("reissued_from_id"),
            "reissued_to_id": obj.get("reissued_to_id"),
            "type": obj.get("type"),
            "card_status": obj.get("card_status"),
            "memo": obj.get("memo"),
            "status_reason": obj.get("status_reason"),
            "bin": obj.get("bin"),
            "card_brand": obj.get("card_brand")
        })
        return _obj

