use serde::{Deserialize, Serialize};
use crate::client::{Client, Response};
use crate::ids::{BillingPortalSessionId, CustomerId};
use crate::params::{Expand, Expandable, Object, Timestamp};
use crate::resources::BillingPortalConfiguration;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct BillingPortalSession {
    pub id: BillingPortalSessionId,
    pub configuration: Expandable<BillingPortalConfiguration>,
    pub created: Timestamp,
    pub customer: String,
    pub flow: Option<PortalFlowsFlow>,
    pub livemode: bool,
    pub locale: Option<BillingPortalSessionLocale>,
    pub on_behalf_of: Option<String>,
    pub return_url: Option<String>,
    pub url: String,
}
impl BillingPortalSession {
    pub fn create(
        client: &Client,
        params: CreateBillingPortalSession<'_>,
    ) -> Response<BillingPortalSession> {
        #[allow(clippy::needless_borrows_for_generic_args)]
        client.post_form("/billing_portal/sessions", ¶ms)
    }
}
impl Object for BillingPortalSession {
    type Id = BillingPortalSessionId;
    fn id(&self) -> Self::Id {
        self.id.clone()
    }
    fn object(&self) -> &'static str {
        "billing_portal.session"
    }
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsFlow {
    pub after_completion: PortalFlowsFlowAfterCompletion,
    pub subscription_cancel: Option<PortalFlowsFlowSubscriptionCancel>,
    pub subscription_update: Option<PortalFlowsFlowSubscriptionUpdate>,
    pub subscription_update_confirm: Option<PortalFlowsFlowSubscriptionUpdateConfirm>,
    #[serde(rename = "type")]
    pub type_: PortalFlowsFlowType,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsFlowAfterCompletion {
    pub hosted_confirmation: Option<PortalFlowsAfterCompletionHostedConfirmation>,
    pub redirect: Option<PortalFlowsAfterCompletionRedirect>,
    #[serde(rename = "type")]
    pub type_: PortalFlowsFlowAfterCompletionType,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsAfterCompletionHostedConfirmation {
    pub custom_message: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsAfterCompletionRedirect {
    pub return_url: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsFlowSubscriptionCancel {
    pub retention: Option<PortalFlowsRetention>,
    pub subscription: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsFlowSubscriptionUpdate {
    pub subscription: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsFlowSubscriptionUpdateConfirm {
    pub discounts: Option<Vec<PortalFlowsSubscriptionUpdateConfirmDiscount>>,
    pub items: Vec<PortalFlowsSubscriptionUpdateConfirmItem>,
    pub subscription: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsRetention {
    pub coupon_offer: Option<PortalFlowsCouponOffer>,
    #[serde(rename = "type")]
    pub type_: PortalFlowsRetentionType,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsCouponOffer {
    pub coupon: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsSubscriptionUpdateConfirmDiscount {
    pub coupon: Option<String>,
    pub promotion_code: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct PortalFlowsSubscriptionUpdateConfirmItem {
    pub id: Option<String>,
    pub price: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub quantity: Option<u64>,
}
#[derive(Clone, Debug, Serialize)]
pub struct CreateBillingPortalSession<'a> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub configuration: Option<&'a str>,
    pub customer: CustomerId,
    #[serde(skip_serializing_if = "Expand::is_empty")]
    pub expand: &'a [&'a str],
    #[serde(skip_serializing_if = "Option::is_none")]
    pub flow_data: Option<CreateBillingPortalSessionFlowData>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub locale: Option<BillingPortalSessionLocale>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub on_behalf_of: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub return_url: Option<&'a str>,
}
impl<'a> CreateBillingPortalSession<'a> {
    pub fn new(customer: CustomerId) -> Self {
        CreateBillingPortalSession {
            configuration: Default::default(),
            customer,
            expand: Default::default(),
            flow_data: Default::default(),
            locale: Default::default(),
            on_behalf_of: Default::default(),
            return_url: Default::default(),
        }
    }
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowData {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub after_completion: Option<CreateBillingPortalSessionFlowDataAfterCompletion>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subscription_cancel: Option<CreateBillingPortalSessionFlowDataSubscriptionCancel>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subscription_update: Option<CreateBillingPortalSessionFlowDataSubscriptionUpdate>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subscription_update_confirm:
        Option<CreateBillingPortalSessionFlowDataSubscriptionUpdateConfirm>,
    #[serde(rename = "type")]
    pub type_: CreateBillingPortalSessionFlowDataType,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataAfterCompletion {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub hosted_confirmation:
        Option<CreateBillingPortalSessionFlowDataAfterCompletionHostedConfirmation>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub redirect: Option<CreateBillingPortalSessionFlowDataAfterCompletionRedirect>,
    #[serde(rename = "type")]
    pub type_: CreateBillingPortalSessionFlowDataAfterCompletionType,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataSubscriptionCancel {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub retention: Option<CreateBillingPortalSessionFlowDataSubscriptionCancelRetention>,
    pub subscription: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataSubscriptionUpdate {
    pub subscription: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataSubscriptionUpdateConfirm {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub discounts:
        Option<Vec<CreateBillingPortalSessionFlowDataSubscriptionUpdateConfirmDiscounts>>,
    pub items: Vec<CreateBillingPortalSessionFlowDataSubscriptionUpdateConfirmItems>,
    pub subscription: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataAfterCompletionHostedConfirmation {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub custom_message: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataAfterCompletionRedirect {
    pub return_url: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataSubscriptionCancelRetention {
    pub coupon_offer: CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionCouponOffer,
    #[serde(rename = "type")]
    pub type_: CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionType,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataSubscriptionUpdateConfirmDiscounts {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub coupon: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub promotion_code: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataSubscriptionUpdateConfirmItems {
    pub id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub price: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub quantity: Option<u64>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionCouponOffer {
    pub coupon: String,
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum BillingPortalSessionLocale {
    Auto,
    Bg,
    Cs,
    Da,
    De,
    El,
    En,
    #[serde(rename = "en-AU")]
    EnAu,
    #[serde(rename = "en-CA")]
    EnCa,
    #[serde(rename = "en-GB")]
    EnGb,
    #[serde(rename = "en-IE")]
    EnIe,
    #[serde(rename = "en-IN")]
    EnIn,
    #[serde(rename = "en-NZ")]
    EnNz,
    #[serde(rename = "en-SG")]
    EnSg,
    Es,
    #[serde(rename = "es-419")]
    Es419,
    Et,
    Fi,
    Fil,
    Fr,
    #[serde(rename = "fr-CA")]
    FrCa,
    Hr,
    Hu,
    Id,
    It,
    Ja,
    Ko,
    Lt,
    Lv,
    Ms,
    Mt,
    Nb,
    Nl,
    Pl,
    Pt,
    #[serde(rename = "pt-BR")]
    PtBr,
    Ro,
    Ru,
    Sk,
    Sl,
    Sv,
    Th,
    Tr,
    Vi,
    Zh,
    #[serde(rename = "zh-HK")]
    ZhHk,
    #[serde(rename = "zh-TW")]
    ZhTw,
}
impl BillingPortalSessionLocale {
    pub fn as_str(self) -> &'static str {
        match self {
            BillingPortalSessionLocale::Auto => "auto",
            BillingPortalSessionLocale::Bg => "bg",
            BillingPortalSessionLocale::Cs => "cs",
            BillingPortalSessionLocale::Da => "da",
            BillingPortalSessionLocale::De => "de",
            BillingPortalSessionLocale::El => "el",
            BillingPortalSessionLocale::En => "en",
            BillingPortalSessionLocale::EnAu => "en-AU",
            BillingPortalSessionLocale::EnCa => "en-CA",
            BillingPortalSessionLocale::EnGb => "en-GB",
            BillingPortalSessionLocale::EnIe => "en-IE",
            BillingPortalSessionLocale::EnIn => "en-IN",
            BillingPortalSessionLocale::EnNz => "en-NZ",
            BillingPortalSessionLocale::EnSg => "en-SG",
            BillingPortalSessionLocale::Es => "es",
            BillingPortalSessionLocale::Es419 => "es-419",
            BillingPortalSessionLocale::Et => "et",
            BillingPortalSessionLocale::Fi => "fi",
            BillingPortalSessionLocale::Fil => "fil",
            BillingPortalSessionLocale::Fr => "fr",
            BillingPortalSessionLocale::FrCa => "fr-CA",
            BillingPortalSessionLocale::Hr => "hr",
            BillingPortalSessionLocale::Hu => "hu",
            BillingPortalSessionLocale::Id => "id",
            BillingPortalSessionLocale::It => "it",
            BillingPortalSessionLocale::Ja => "ja",
            BillingPortalSessionLocale::Ko => "ko",
            BillingPortalSessionLocale::Lt => "lt",
            BillingPortalSessionLocale::Lv => "lv",
            BillingPortalSessionLocale::Ms => "ms",
            BillingPortalSessionLocale::Mt => "mt",
            BillingPortalSessionLocale::Nb => "nb",
            BillingPortalSessionLocale::Nl => "nl",
            BillingPortalSessionLocale::Pl => "pl",
            BillingPortalSessionLocale::Pt => "pt",
            BillingPortalSessionLocale::PtBr => "pt-BR",
            BillingPortalSessionLocale::Ro => "ro",
            BillingPortalSessionLocale::Ru => "ru",
            BillingPortalSessionLocale::Sk => "sk",
            BillingPortalSessionLocale::Sl => "sl",
            BillingPortalSessionLocale::Sv => "sv",
            BillingPortalSessionLocale::Th => "th",
            BillingPortalSessionLocale::Tr => "tr",
            BillingPortalSessionLocale::Vi => "vi",
            BillingPortalSessionLocale::Zh => "zh",
            BillingPortalSessionLocale::ZhHk => "zh-HK",
            BillingPortalSessionLocale::ZhTw => "zh-TW",
        }
    }
}
impl AsRef<str> for BillingPortalSessionLocale {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for BillingPortalSessionLocale {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for BillingPortalSessionLocale {
    fn default() -> Self {
        Self::Auto
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum CreateBillingPortalSessionFlowDataAfterCompletionType {
    HostedConfirmation,
    PortalHomepage,
    Redirect,
}
impl CreateBillingPortalSessionFlowDataAfterCompletionType {
    pub fn as_str(self) -> &'static str {
        match self {
            CreateBillingPortalSessionFlowDataAfterCompletionType::HostedConfirmation => {
                "hosted_confirmation"
            }
            CreateBillingPortalSessionFlowDataAfterCompletionType::PortalHomepage => {
                "portal_homepage"
            }
            CreateBillingPortalSessionFlowDataAfterCompletionType::Redirect => "redirect",
        }
    }
}
impl AsRef<str> for CreateBillingPortalSessionFlowDataAfterCompletionType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for CreateBillingPortalSessionFlowDataAfterCompletionType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for CreateBillingPortalSessionFlowDataAfterCompletionType {
    fn default() -> Self {
        Self::HostedConfirmation
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionType {
    CouponOffer,
}
impl CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionType {
    pub fn as_str(self) -> &'static str {
        match self {
            CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionType::CouponOffer => {
                "coupon_offer"
            }
        }
    }
}
impl AsRef<str> for CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for CreateBillingPortalSessionFlowDataSubscriptionCancelRetentionType {
    fn default() -> Self {
        Self::CouponOffer
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum CreateBillingPortalSessionFlowDataType {
    PaymentMethodUpdate,
    SubscriptionCancel,
    SubscriptionUpdate,
    SubscriptionUpdateConfirm,
}
impl CreateBillingPortalSessionFlowDataType {
    pub fn as_str(self) -> &'static str {
        match self {
            CreateBillingPortalSessionFlowDataType::PaymentMethodUpdate => "payment_method_update",
            CreateBillingPortalSessionFlowDataType::SubscriptionCancel => "subscription_cancel",
            CreateBillingPortalSessionFlowDataType::SubscriptionUpdate => "subscription_update",
            CreateBillingPortalSessionFlowDataType::SubscriptionUpdateConfirm => {
                "subscription_update_confirm"
            }
        }
    }
}
impl AsRef<str> for CreateBillingPortalSessionFlowDataType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for CreateBillingPortalSessionFlowDataType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for CreateBillingPortalSessionFlowDataType {
    fn default() -> Self {
        Self::PaymentMethodUpdate
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum PortalFlowsFlowAfterCompletionType {
    HostedConfirmation,
    PortalHomepage,
    Redirect,
}
impl PortalFlowsFlowAfterCompletionType {
    pub fn as_str(self) -> &'static str {
        match self {
            PortalFlowsFlowAfterCompletionType::HostedConfirmation => "hosted_confirmation",
            PortalFlowsFlowAfterCompletionType::PortalHomepage => "portal_homepage",
            PortalFlowsFlowAfterCompletionType::Redirect => "redirect",
        }
    }
}
impl AsRef<str> for PortalFlowsFlowAfterCompletionType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for PortalFlowsFlowAfterCompletionType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for PortalFlowsFlowAfterCompletionType {
    fn default() -> Self {
        Self::HostedConfirmation
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum PortalFlowsFlowType {
    PaymentMethodUpdate,
    SubscriptionCancel,
    SubscriptionUpdate,
    SubscriptionUpdateConfirm,
}
impl PortalFlowsFlowType {
    pub fn as_str(self) -> &'static str {
        match self {
            PortalFlowsFlowType::PaymentMethodUpdate => "payment_method_update",
            PortalFlowsFlowType::SubscriptionCancel => "subscription_cancel",
            PortalFlowsFlowType::SubscriptionUpdate => "subscription_update",
            PortalFlowsFlowType::SubscriptionUpdateConfirm => "subscription_update_confirm",
        }
    }
}
impl AsRef<str> for PortalFlowsFlowType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for PortalFlowsFlowType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for PortalFlowsFlowType {
    fn default() -> Self {
        Self::PaymentMethodUpdate
    }
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum PortalFlowsRetentionType {
    CouponOffer,
}
impl PortalFlowsRetentionType {
    pub fn as_str(self) -> &'static str {
        match self {
            PortalFlowsRetentionType::CouponOffer => "coupon_offer",
        }
    }
}
impl AsRef<str> for PortalFlowsRetentionType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}
impl std::fmt::Display for PortalFlowsRetentionType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.as_str().fmt(f)
    }
}
impl std::default::Default for PortalFlowsRetentionType {
    fn default() -> Self {
        Self::CouponOffer
    }
}