use serde::{Deserialize, Serialize};
use crate::ids::IssuingTokenId;
use crate::params::{Expandable, Object, Timestamp};
use crate::resources::IssuingCard;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct IssuingToken {
    pub id: IssuingTokenId,
    pub card: Expandable<IssuingCard>,
    pub created: Timestamp,
    pub device_fingerprint: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub last4: Option<String>,
    pub livemode: bool,
    pub network: IssuingTokenNetwork,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub network_data: Option<IssuingNetworkTokenNetworkData>,
    pub network_updated_at: Timestamp,
    pub status: IssuingTokenStatus,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub wallet_provider: Option<IssuingTokenWalletProvider>,
}
impl Object for IssuingToken {
    type Id = IssuingTokenId;
    fn id(&self) -> Self::Id {
        self.id.clone()
    }
    fn object(&self) -> &'static str {
        "issuing.token"
    }
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct IssuingNetworkTokenNetworkData {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub device: Option<IssuingNetworkTokenDevice>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub mastercard: Option<IssuingNetworkTokenMastercard>,
    #[serde(rename = "type")]
    pub type_: IssuingNetworkTokenNetworkDataType,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub visa: Option<IssuingNetworkTokenVisa>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub wallet_provider: Option<IssuingNetworkTokenWalletProvider>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct IssuingNetworkTokenDevice {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub device_fingerprint: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub ip_address: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub location: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub phone_number: Option<String>,
    #[serde(rename = "type")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub type_: Option<IssuingNetworkTokenDeviceType>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct IssuingNetworkTokenMastercard {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub card_reference_id: Option<String>,
    pub token_reference_id: String,
    pub token_requestor_id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub token_requestor_name: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct IssuingNetworkTokenVisa {
    pub card_reference_id: String,
    pub token_reference_id: String,
    pub token_requestor_id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub token_risk_score: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct IssuingNetworkTokenWalletProvider {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub account_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub account_trust_score: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub card_number_source: Option<IssuingNetworkTokenWalletProviderCardNumberSource>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cardholder_address: Option<IssuingNetworkTokenAddress>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cardholder_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub device_trust_score: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub hashed_account_email_address: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reason_codes: Option<Vec<IssuingNetworkTokenWalletProviderReasonCodes>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub suggested_decision: Option<IssuingNetworkTokenWalletProviderSuggestedDecision>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub suggested_decision_version: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct IssuingNetworkTokenAddress {
    pub line1: String,
    pub postal_code: String,
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingNetworkTokenDeviceType {
    Other,
    Phone,
    Watch,
}
impl IssuingNetworkTokenDeviceType {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingNetworkTokenDeviceType::Other => "other",
            IssuingNetworkTokenDeviceType::Phone => "phone",
            IssuingNetworkTokenDeviceType::Watch => "watch",
        }
    }
}
impl AsRef<str> for IssuingNetworkTokenDeviceType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingNetworkTokenDeviceType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingNetworkTokenDeviceType {
    fn default() -> Self {
        Self::Other
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingNetworkTokenNetworkDataType {
    Mastercard,
    Visa,
}
impl IssuingNetworkTokenNetworkDataType {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingNetworkTokenNetworkDataType::Mastercard => "mastercard",
            IssuingNetworkTokenNetworkDataType::Visa => "visa",
        }
    }
}
impl AsRef<str> for IssuingNetworkTokenNetworkDataType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingNetworkTokenNetworkDataType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingNetworkTokenNetworkDataType {
    fn default() -> Self {
        Self::Mastercard
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingNetworkTokenWalletProviderCardNumberSource {
    App,
    Manual,
    OnFile,
    Other,
}
impl IssuingNetworkTokenWalletProviderCardNumberSource {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingNetworkTokenWalletProviderCardNumberSource::App => "app",
            IssuingNetworkTokenWalletProviderCardNumberSource::Manual => "manual",
            IssuingNetworkTokenWalletProviderCardNumberSource::OnFile => "on_file",
            IssuingNetworkTokenWalletProviderCardNumberSource::Other => "other",
        }
    }
}
impl AsRef<str> for IssuingNetworkTokenWalletProviderCardNumberSource {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingNetworkTokenWalletProviderCardNumberSource {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingNetworkTokenWalletProviderCardNumberSource {
    fn default() -> Self {
        Self::App
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingNetworkTokenWalletProviderReasonCodes {
    AccountCardTooNew,
    AccountRecentlyChanged,
    AccountTooNew,
    AccountTooNewSinceLaunch,
    AdditionalDevice,
    DataExpired,
    DeferIdVDecision,
    DeviceRecentlyLost,
    GoodActivityHistory,
    HasSuspendedTokens,
    HighRisk,
    InactiveAccount,
    LongAccountTenure,
    LowAccountScore,
    LowDeviceScore,
    LowPhoneNumberScore,
    NetworkServiceError,
    OutsideHomeTerritory,
    ProvisioningCardholderMismatch,
    ProvisioningDeviceAndCardholderMismatch,
    ProvisioningDeviceMismatch,
    SameDeviceNoPriorAuthentication,
    SameDeviceSuccessfulPriorAuthentication,
    SoftwareUpdate,
    SuspiciousActivity,
    TooManyDifferentCardholders,
    TooManyRecentAttempts,
    TooManyRecentTokens,
}
impl IssuingNetworkTokenWalletProviderReasonCodes {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingNetworkTokenWalletProviderReasonCodes::AccountCardTooNew => "account_card_too_new",
            IssuingNetworkTokenWalletProviderReasonCodes::AccountRecentlyChanged => "account_recently_changed",
            IssuingNetworkTokenWalletProviderReasonCodes::AccountTooNew => "account_too_new",
            IssuingNetworkTokenWalletProviderReasonCodes::AccountTooNewSinceLaunch => "account_too_new_since_launch",
            IssuingNetworkTokenWalletProviderReasonCodes::AdditionalDevice => "additional_device",
            IssuingNetworkTokenWalletProviderReasonCodes::DataExpired => "data_expired",
            IssuingNetworkTokenWalletProviderReasonCodes::DeferIdVDecision => "defer_id_v_decision",
            IssuingNetworkTokenWalletProviderReasonCodes::DeviceRecentlyLost => "device_recently_lost",
            IssuingNetworkTokenWalletProviderReasonCodes::GoodActivityHistory => "good_activity_history",
            IssuingNetworkTokenWalletProviderReasonCodes::HasSuspendedTokens => "has_suspended_tokens",
            IssuingNetworkTokenWalletProviderReasonCodes::HighRisk => "high_risk",
            IssuingNetworkTokenWalletProviderReasonCodes::InactiveAccount => "inactive_account",
            IssuingNetworkTokenWalletProviderReasonCodes::LongAccountTenure => "long_account_tenure",
            IssuingNetworkTokenWalletProviderReasonCodes::LowAccountScore => "low_account_score",
            IssuingNetworkTokenWalletProviderReasonCodes::LowDeviceScore => "low_device_score",
            IssuingNetworkTokenWalletProviderReasonCodes::LowPhoneNumberScore => "low_phone_number_score",
            IssuingNetworkTokenWalletProviderReasonCodes::NetworkServiceError => "network_service_error",
            IssuingNetworkTokenWalletProviderReasonCodes::OutsideHomeTerritory => "outside_home_territory",
            IssuingNetworkTokenWalletProviderReasonCodes::ProvisioningCardholderMismatch => "provisioning_cardholder_mismatch",
            IssuingNetworkTokenWalletProviderReasonCodes::ProvisioningDeviceAndCardholderMismatch => "provisioning_device_and_cardholder_mismatch",
            IssuingNetworkTokenWalletProviderReasonCodes::ProvisioningDeviceMismatch => "provisioning_device_mismatch",
            IssuingNetworkTokenWalletProviderReasonCodes::SameDeviceNoPriorAuthentication => "same_device_no_prior_authentication",
            IssuingNetworkTokenWalletProviderReasonCodes::SameDeviceSuccessfulPriorAuthentication => "same_device_successful_prior_authentication",
            IssuingNetworkTokenWalletProviderReasonCodes::SoftwareUpdate => "software_update",
            IssuingNetworkTokenWalletProviderReasonCodes::SuspiciousActivity => "suspicious_activity",
            IssuingNetworkTokenWalletProviderReasonCodes::TooManyDifferentCardholders => "too_many_different_cardholders",
            IssuingNetworkTokenWalletProviderReasonCodes::TooManyRecentAttempts => "too_many_recent_attempts",
            IssuingNetworkTokenWalletProviderReasonCodes::TooManyRecentTokens => "too_many_recent_tokens",
        }
    }
}
impl AsRef<str> for IssuingNetworkTokenWalletProviderReasonCodes {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingNetworkTokenWalletProviderReasonCodes {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingNetworkTokenWalletProviderReasonCodes {
    fn default() -> Self {
        Self::AccountCardTooNew
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingNetworkTokenWalletProviderSuggestedDecision {
    Approve,
    Decline,
    RequireAuth,
}
impl IssuingNetworkTokenWalletProviderSuggestedDecision {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingNetworkTokenWalletProviderSuggestedDecision::Approve => "approve",
            IssuingNetworkTokenWalletProviderSuggestedDecision::Decline => "decline",
            IssuingNetworkTokenWalletProviderSuggestedDecision::RequireAuth => "require_auth",
        }
    }
}
impl AsRef<str> for IssuingNetworkTokenWalletProviderSuggestedDecision {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingNetworkTokenWalletProviderSuggestedDecision {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingNetworkTokenWalletProviderSuggestedDecision {
    fn default() -> Self {
        Self::Approve
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingTokenNetwork {
    Mastercard,
    Visa,
}
impl IssuingTokenNetwork {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingTokenNetwork::Mastercard => "mastercard",
            IssuingTokenNetwork::Visa => "visa",
        }
    }
}
impl AsRef<str> for IssuingTokenNetwork {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingTokenNetwork {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingTokenNetwork {
    fn default() -> Self {
        Self::Mastercard
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingTokenStatus {
    Active,
    Deleted,
    Requested,
    Suspended,
}
impl IssuingTokenStatus {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingTokenStatus::Active => "active",
            IssuingTokenStatus::Deleted => "deleted",
            IssuingTokenStatus::Requested => "requested",
            IssuingTokenStatus::Suspended => "suspended",
        }
    }
}
impl AsRef<str> for IssuingTokenStatus {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingTokenStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingTokenStatus {
    fn default() -> Self {
        Self::Active
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum IssuingTokenWalletProvider {
    ApplePay,
    GooglePay,
    SamsungPay,
}
impl IssuingTokenWalletProvider {
    pub fn as_str(self) -> &'static str {
        match self {
            IssuingTokenWalletProvider::ApplePay => "apple_pay",
            IssuingTokenWalletProvider::GooglePay => "google_pay",
            IssuingTokenWalletProvider::SamsungPay => "samsung_pay",
        }
    }
}
impl AsRef<str> for IssuingTokenWalletProvider {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for IssuingTokenWalletProvider {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for IssuingTokenWalletProvider {
    fn default() -> Self {
        Self::ApplePay
    }
}