import {
  Element,
  ElementType,
  CardElementOptions,
  CardNumberElementOptions,
  ExpiryDateElementOptions,
  CvcElementOptions,
  FullFeaturedCardElementOptions,
  WechatElementOptions,
  ApplePayButtonOptions,
  GooglePayButtonOptions,
  ApplePayButtonElementType,
  GooglePayButtonElementType,
  CardElementType,
  DropInElementType,
  CardNumberElementType,
  ExpiryDateElementType,
  CvcElementType,
  WechatElementType,
  FullFeaturedCardElementType,
  RedirectElementType,
  QrcodeElementType,
  CardNetwork,
  Appearance,
} from './element';
import { QrcodeElementOptions } from './qrcodeElement';
import { Intent, PaymentMethodBasicInfo } from './cardNumber';
import {
  BoxStyle,
  PaymentMethodType,
  ApplePayHppOrDropInRequestOptions,
  GooglePayHppRequestOptions,
  ContactField,
  LPMFlows,
} from './element';
import { getDeviceFingerprint } from './fraud';
import { DropInElementOptions } from './dropInElement';
import { RedirectElementOptions } from './redirectElement';

export type Locale =
  | 'ar'
  | 'da'
  | 'de'
  | 'en'
  | 'es'
  | 'fi'
  | 'fr'
  | 'id'
  | 'it'
  | 'ja'
  | 'ko'
  | 'ms'
  | 'nl'
  | 'pl'
  | 'pt'
  | 'ro'
  | 'ru'
  | 'sv'
  | 'zh'
  | 'zh-HK';

/**
 * Global option to customize font styles of Elements. You can specify font options using `family`, `src` and `weight` attributes.
 */
export interface FontOptions {
  /**
   * The font-family property, for example, `AxLLCircular`.
   * https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
   */
  family?: string;
  /**
   * The font-source property, for example, `https://checkout.airwallex.com/fonts/CircularXXWeb/CircularXXWeb-Regular.woff2`.
   * https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face
   */
  src?: string;
  /**
   * The font-weight property. Supported font weights include: regular (400) and bold (700).
   * https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
   */
  weight?: string | number;
}

/**
 *  The Airwallex integration environment your site would like to connect with.
 *
 *  @defaultValue "prod"
 */
export type AirwallexEnv = 'demo' | 'prod';

/**
 *  The checkout mode for the shopper.
 *  @defaultValue `'payment'`
 */
export type Mode = 'payment' | 'recurring';

/**
 * Describes the type of transaction being performed in order to customize the submit button text.
 * @defaultValue `'pay'`
 */
export type SubmitType = 'pay' | 'book' | 'subscribe' | 'save';

export type AuthorizationType = 'pre_auth' | 'final_auth';

/**
 * Global option to initialize Airwallex Web Components SDK.
 */
export interface InitOptions {
  /**
   * The Airwallex integration environment your site would like to connect with.
   *
   * @defaultValue `'prod'`
   */
  env?: AirwallexEnv;
  /**
   * The locale for your website. Defaults to the browser's locale; however, if the browser's locale is not supported, it will default to 'en'.
   */
  locale?: Locale;
  /**
   * @deprecated This field is no longer used.
   */
  origin?: string;
  /**
   * Global option to customize font styles of Elements.
   */
  fonts?: FontOptions[];
}

/**
 * Theme configuration options for Hosted Payment Page.
 */
export interface HppTheme extends BoxStyle {
  fonts?: FontOptions[];
}

export interface RecurringOptions extends HppRecurringOptions {
  /**
   * Whether the merchant or customer should trigger subsequent payments.
   * @defaultValue `'customer'`
   */
  next_triggered_by?: 'merchant' | 'customer';
  /**
   * Whether subsequent payments are `'scheduled'` or `'unscheduled'`. Only applicable when `next_triggered_by` is `'merchant'`.
   *
   * @defaultValue `'unscheduled'`
   */
  merchant_trigger_reason?: 'scheduled' | 'unscheduled';
  /**
   * The three-letter ISO currency code representing the currency of the initial Payment Intent. Only applicable to card payment method.
   */
  currency?: string;
  /**
   * The ID of the connected account linked to the platform.
   * The platform should indicate the connected entity in the transaction only when platform is the owner of the transaction.
   */
  connected_account_id?: string;
  /**
   *  Set it to `true` if you want to skip 3DS regardless of the risk score and Strong Customer Authentication (SCA) regulation. Only applicable when it's a card recurring flow.
   * @deprecated use {@link three_ds_action} instead
   * @hidden
   */
  skip_3ds?: boolean;
  /**
   *  Set it to `SKIP_3DS` if you want to skip 3DS regardless of the risk score and Strong Customer Authentication (SCA) regulation. Only applicable when it's a card recurring flow.
   *  Set it to `FORCE_3DS` if you want to force 3DS regardless of the risk score and Strong Customer Authentication (SCA) regulation. Only applicable when it's a card recurring flow.
   */
  three_ds_action?: 'SKIP_3DS' | 'FORCE_3DS';
  /**
   *  Descriptor that may be displayed to the customer during verification.
   */
  descriptor?: string;
}

export interface HppRecurringOptions {
  /**
   * Currently we supports card and alipay(exclude alipaycn) recurring flow
   * For alipay, merchant does not need to config anything
   * For card, merchant needs to provide related configurations
   * @deprecated use {@link RecurringOptions} instead
   * @hidden
   */
  card?: {
    /**
     * Whether the `'merchant'` or `'customer'` should trigger subsequent payments.
     *
     */
    next_triggered_by?: 'merchant' | 'customer';
    /**
     * Whether subsequent payments are `'scheduled'` or `'unscheduled'`. Only applicable when `next_triggered_by` is `'merchant'`.
     *
     * @defaultValue `'unscheduled'`
     */
    merchant_trigger_reason?: 'scheduled' | 'unscheduled';
    /**
     * The three-letter ISO currency code representing the currency of the initial Payment Intent. Only applicable to card payment method.
     */
    currency?: string;
    /**
     * The ID of the connected account linked to the platform.
     * The platform should indicate the connected entity in the transaction only when platform is the owner of the transaction.
     */
    connected_account_id?: string;
  };
}

interface WeChatPayFlow {
  desktopFlow?: LPMFlows;
  mobileFlow?: LPMFlows;
}

export interface Layout {
  /**
   *  Specify the layout for the payment elements. By default, `accordion` layout is used on desktop and `tab` layout is used on mobile.
   */
  type?: 'tab' | 'accordion';
  /**
   *  By default, the payment method icon is not visible when there is only one payment method. Set it to `true` if you want to always show the payment method icon.
   *  @defaultValue `false`
   */
  alwaysShowMethodLabel?: boolean;
}


export interface HppLayout {
  /**
   *  Specify the layout for the payment elements. By default, `accordion` layout is used on desktop and `tab` layout is used on mobile.
   */
  type?: 'tab' | 'accordion';
}

/**
 * Configuration option for Hosted Payment Page(HPP), a checkout solution that redirects shoppers to a secure, pre-built payment page hosted by Airwallex.
 */
export interface HostPaymentPage {
  /**
   *  The Airwallex integration environment your site would like to connect with.
   *
   *  @defaultValue `prod`
   */
  env?: AirwallexEnv;
  /**
   * The ID of the Payment Intent you would like to checkout. Required when `mode` is `'payment'`.
   */
  intent_id?: string;
  /**
   * The `client_secret` of the Payment Intent when Payment Intent is provided. Otherwise, this should be the `client_secret` of the Customer object.
   *
   */
  client_secret: string;

  /**
   * @deprecated use {@link appearance} instead
   */
  theme?: HppTheme;
  /**
   * Page appearance customization options for Hosted Payment Page.
   *
   * You can configure:
   *
   * - `mode`: Choose between `'dark'` and `'light'` mode.
   *
   * - `variables`: Set `colorBrand`, `colorText`, `colorBackground` properties.
   */
  appearance?: Appearance;
  /**
   * The payment consent details.
   */
  payment_consent?: PaymentConsentOptions;
  /**
   * The ID of the Customer used in registered user checkout. Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Customers/Intro)
   * This field is required when `mode` is `'recurring'`.
   */
  customer_id?: string;
  /**
   * The payment methods your website would like to integrate with.
   * @deprecated use {@link methods} instead
   */
  components?: Array<PaymentMethodType>;
  /**
   * Specify the payment methods and their order for display on the payment page. By default, the order will be based on the order configured in [Get available payment method types API](https://www.airwallex.com/docs/api/v1/pa/config/payment_method_types#/Payment_Acceptance/Config/_api_v1_pa_config_payment_method_types/get), with 'applepay', 'googlepay' and 'paypal' displayed at the top if they're supported.   Note: Only payment methods supported for the specified currency and country_code will be shown on the payment page.
   */
  methods?: Array<PaymentMethodType>;
  /**
   * Whether the amount should be captured automatically upon successful payment authorization.
   * Set it to `false` if you want to place a hold on the payment method and capture the funds sometime later.
   * @defaultValue `true`
   */
  autoCapture?: boolean;
  /**
   * The authorization type for the card payment.
   * Set it to `'pre_auth'` if you want to place a hold on your customer’s card for more than 7 days, i.e., extend the authorization time window.
   * Currently `'pre_auth'` is only available when the card brand is Visa or Mastercard. `autoCapture` will be automatically set to `false` if you enable `'pre_auth'`.
   * @defaultValue `'final_auth'`
   */
  authorizationType?: AuthorizationType;
  /**
   * Whether you require the shopper to provide CVC when they checkout with a network tokenized card.
   */
  cvcRequired?: boolean;
  /**
   * One or more card networks that you support.
   */
  allowedCardNetworks?: CardNetwork[];
  /**
   * The options for WeChat Pay.
   */
  wechatpay?: WeChatPayFlow;
  /**
   * The HTTPS URL to redirect shoppers when payment is successful.
   */
  successUrl?: string;
  /**
   * The HTPS URL to redirect shoppers when payment fails.
   */
  failUrl?: string;
  /**
   * The layout of the Hosted Payment Page.
   */
  layout?: HppLayout;
  /**
   * The URL of your website logo to display on the header of the Hosted Payment Page.
   */
  logoUrl?: string;
  /**
   * The locale for your website. Defaults to the browser's locale; however, if the browser's locale is not supported, it will default to 'en'.
   */
  locale?: Locale;
  /**
   * Used to increase the likelihood of 3DS frictionless checkout.
   * Set this to `true` if you want the payment form to collect billing information from the shopper. Only applies to card payment method.
   * @deprecated please use {@link requiredBillingContactFields} instead
   */
  withBilling?: boolean;
  /**
   * The billing information that you require from the user in order to process the transaction.
   */
  requiredBillingContactFields?: ContactField[];
  /**
   * The checkout mode for the shopper.
   * @defaultValue `'payment'`
   */
  mode?: Mode;
  /**
   * Options for recurring flow.
   */
  recurringOptions?: RecurringOptions;
  /**
   * Checkout configuration options for Apple Pay.
   *
   */
  applePayRequestOptions?: ApplePayHppOrDropInRequestOptions;
  /**
   * Checkout configuration options for Google Pay.
   */
  googlePayRequestOptions?: GooglePayHppRequestOptions;
  /**
   *  The three-letter ISO currency code representing the currency of the Payment Intent or Payment Consent.  Only payment methods supported for the specified `currency` will be shown on the payment page.
   */
  currency: string;
  /**
   * When using Payments for Platforms, specify the ID of the connected account associated with the payment if you want to use its information to process the payment.
   * For example, the statement descriptor displayed on the shopper's credit card or bank statement and the payment methods activated by the connected account.
   *
   */
  platformConnectedAccount?: string;
  /**
   * The two-letter ISO country code of the shopper's country.
   * If the country_code is not provided, we will determine it based on the shopper's IP address.
   * However, some payment methods, such as iDEAL, are only available to shoppers in specific countries.
   * If the shopper is not located in a supported country, the corresponding payment method may not be displayed.
   * To ensure that your customers can successfully complete their payments using the appropriate methods, we strongly recommend that you explicitly pass the country_code to us.
   */
  country_code?: string;
  /**
   * The shopper's full name.
   */
  shopper_name?: string;
  /**
   * The shopper's phone number.
   */
  shopper_phone?: string;
  /**
   * The shopper's email address.
   */
  shopper_email?: string;
  showTermLink?: boolean;
  /**
   * Whether auto redirect to the URL specified by the merchant should be disabled.
   * @defaultValue `false`
   */
  disableAutoRedirect?: boolean;
  /**
   * Specifies whether the card payment method should be automatically saved for future transactions.
   *
   * This parameter is only effective in payment mode when a `customer_id` is provided.
   *
   * - If set to `true`, the "Save my card for future payments" checkbox will be preselected by default.
   * - If set to `false`, the checkbox will remain unchecked, requiring the shopper to manually opt in.
   *
   * @defaultValue `true`
   */
  autoSaveCardForFuturePayments?: boolean;

  /**
   * Describes the type of transaction being performed in order to customize the submit button text.
   * Available options are 'pay', 'book', 'subscribe', 'save'.
   * If blank, the default value will be `'pay'`
   * @defaultValue `'pay'`
   */
  submitType?: SubmitType;
}

/**
 * Billing address details. Only applicable to card payment method.
 */
export interface Address {
  city: string;
  /**
   * The two-letter ISO country code of the shopper's country.
   * https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes
   */
  country_code: string;
  /**
   * Local post code.
   */
  postcode: string;
  state: string;
  street: string;
}
/**
 * Billing information. Only applies to card payment method.
 */
export interface Billing {
  /**
   * Billing email address. Refer to https://en.wikipedia.org/wiki/Email_address
   */
  email: string;
  first_name: string;
  last_name: string;
  date_of_birth?: string;
  phone_number?: string;
  /**
   * Billing address
   */
  address: Address;
}

export interface PaymentMethod {
  /**
   * Create a card Element by calling createElement() with `cardNumber` Element type.
   */
  element: Element;
  /**
   * The ID of a payment method if already exists. You can create a new payment method by calling createPaymentMethod().
   */
  methodId?: string;
  /**
   * The client_secret returned in the response when you create a Payment Intent.
   */
  client_secret?: string;
  /**
   * The payment intent you would like to checkout
   * Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Payment_Intents/)
   * @deprecated use {@link intent_id} instead
   */
  id?: string;
  /**
   * The ID of the Payment Intent you would like to checkout. Required when `mode` is `'payment'`.
   * Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Payment_Intents/)
   */
  intent_id?: string;
  /**
   * The ID of the Customer used in registered user checkout. Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Customers/Intro)
   * This field is required when `mode` is `'recurring'`.
   */
  customer_id?: string;
  /**
   * Whether to save this payment method for future payments or not.
   */
  save_payment_method?: boolean;
  /**
   * The payment method details returned by calling createPaymentMethod().
   */
  payment_method?: {
    /**
     *  Information about the card.
     */
    card: {
      /**
       * The cardholder name.
       */
      name?: string;
    };
    /**
     * Card billing information if exists.
     */
    billing?: Billing;
  };
  /**
   * Additional configuration to confirm the Payment Intent. Only applies to card payments.
   */
  payment_method_options?: {
    /**
     *  Only applies to card payments.
     */
    card?: {
      /**
       * Whether the amount should be captured automatically upon successful payment authorization.
       * Set it to `false` if you want to place a hold on the payment method and capture the funds sometime later.
       * @defaultValue `true`
       */
      auto_capture?: boolean;
      /**
       * The authorization type for the card payment.
       * Set it to `'pre_auth'` if you want to place a hold on your customer’s card for more than 7 days, i.e., extend the authorization time window.
       * Currently `'pre_auth'` is only available when the card brand is Visa or Mastercard. `autoCapture` will be automatically set to `false` if you enable `pre_auth`.
       * @defaultValue `'final_auth'`
       */
      authorization_type?: AuthorizationType;
    };
  };
  /**
   * Response error when createPaymentMethod() fails.
   */
  error?: {
    /**
     * Free text message in English.
     */
    message?: string;
    /**
     * String code, will support in the future
     */
    code?: string;
  };
}

export interface PaymentMethodObjType {
  /**
   *  Information about the card.
   */
  card: {
    /**
     * The cardholder name.
     */
    name?: string;
  };
  /**
   * Card billing information if exists.
   */
  billing?: Billing;
}

export interface PaymentMethodOptionsType {
  /**
   *  Only applies to card payments.
   */
  card?: {
    /**
     * Whether the amount should be captured automatically upon successful payment authorization.
     * Set it to `false` if you want to place a hold on the payment method and capture the funds sometime later.
     * @defaultValue `true`
     */
    auto_capture?: boolean;
    /**
     * The authorization type for the card payment.
     * Set it to `'pre_auth'` if you want to place a hold on your customer’s card for more than 7 days, i.e., extend the authorization time window.
     * Currently `'pre_auth'` is only available when the card brand is Visa or Mastercard. `autoCapture` will be automatically set to `false` if you enable `pre_auth`.
     * @defaultValue `'final_auth'`
     */
    authorization_type?: AuthorizationType;
  };
}

/**
 * Terms of use for recurring payments or payment agreements.
 */
export interface TermsOfUse {
  /**
   * The types of Payto agreements. Should be one of FIXED, VARIABLE.
   */
  payment_amount_type: 'FIXED' | 'VARIABLE';

  /**
   * The fixed payment amount that can be charged for a single payment.
   * Required if payment_amount_type is FIXED.
   */
  fixed_payment_amount?: number;

  /**
   * The maximum payment amount that can be charged for a single payment.
   * Optional if payment_amount_type is VARIABLE.
   */
  max_payment_amount?: number;

  /**
   * The first payment. It could include the costs associated with the first debited amount.
   * Optional if payment_amount_type is VARIABLE.
   */
  first_payment_amount?: number;

  /**
   * Payment schedule details.
   */
  payment_schedule?: {
    /**
     * The number of period units between billing cycles.
     * For example, the payment cycle is one month if period=1 and period_unit=MONTH.
     * Required when merchant_trigger_reason = scheduled.
     */
    period: number;

    /**
     * Specifies billing frequency. One of DAY, WEEK, MONTH, and YEAR.
     * Required when merchant_trigger_reason = scheduled.
     */
    period_unit: 'DAY' | 'WEEK' | 'MONTH' | 'YEAR';
  };

  /**
   * The total number of billing cycles of the payment schedule.
   * If null, the mandate will continue indefinitely.
   */
  total_billing_cycles?: number;

  /**
   * The granularity per billing cycle.
   * Required when payment_schedule.period_unit is WEEK, MONTH, or YEAR.
   */
  billing_cycle_charge_day?: number;
  /**
   * The currency of this payment.
   */
  payment_currency: string;

  /**
   * Start date to expect payment request.
   * @example "2025-01-01"
   */
  start_date: string;

  /**
   * End date to expect payment request.
   * @example "2025-01-01"
   */
  end_date?: string;
}

export interface PaymentConsentOptions {
  /**
   * Indicate the current payment initiator.
   */
  next_triggered_by: 'merchant' | 'customer';
  /**
   * The trigger reasons for CoF. One of installments, unscheduled and scheduled
   *
   * @defaultValue `'unscheduled'`
   */
  merchant_trigger_reason?: 'scheduled' | 'unscheduled' | 'installments';
  /**
   * Specifies the agreed legal and regulatory terms governing the recurring payment arrangement between the merchant and the customer.
   */
  terms_of_use?: TermsOfUse;
}

/**
 * Interface of the data when `element.confirm(data)` is called.
 */
export interface PaymentMethodRequestData {
  /**
   * The ID of a payment method if already exists. You can create a new payment method by calling createPaymentMethod().
   * @deprecated use {@link payment_method_id} instead
   */
  methodId?: string;
  /**
   * The ID of a payment method if already exists. You can create a new payment method by calling createPaymentMethod().
   */
  payment_method_id?: string;
  /**
   * The `client_secret` of the Payment Intent when Payment Intent is provided. Otherwise, this should be the `client_secret` of the Customer object.
   */
  client_secret: string;
  /**
   * The payment intent you would like to checkout
   * Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Payment_Intents/Intro)
   * @deprecated use {@link intent_id} instead
   */
  id?: string;
  /**
   * The ID of the Payment Intent you would like to checkout. Required when `mode` is `'payment'`.
   * Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Payment_Intents/)
   */
  intent_id?: string;
  /**
   * The ID of the Customer used in registered user checkout. Refer to [Airwallex Client API](https://www.airwallex.com/docs/api#/Payment_Acceptance/Customers/Intro)
   * This field is required when `mode` is `'recurring'`.
   */
  customer_id?: string;
  /**
   * The payment consent details.
   */
  payment_consent?: PaymentConsentOptions;
  /**
   * The payment method details returned by calling createPaymentMethod().
   */
  payment_method?: PaymentMethodObjType;
  /**
   * Additional configuration to confirm the Payment Intent. Only applies to card payments.
   */
  payment_method_options?: PaymentMethodOptionsType;
  /**
   * Response error when createPaymentMethod() fails.
   */
  error?: {
    /**
     * Free text message in English.
     */
    message?: string;
    /**
     * String code, will support in the future
     */
    code?: string;
  };
}

/**
 * Call this method to initialize the Element after loadAirwallex() returns.
 */
export declare const init: (options?: InitOptions | undefined) => void;

/**
  * Function to redirect the shopper in a Hosted Payment Page(HPP) integration.
  * @example
  ```ts
  import { init } from '@airwallex/components-sdk';

  const { payments } = await init({
    env: 'demo', // Choose the Airwallex environment ('demo' or 'prod')
    enabledElements: ['payments'],
  });
  payments.redirectToCheckout({
    intent_id: 'replace-with-your-intent-id',
    client_secret: 'replace-with-your-client-secret',
    currency: 'replace-with-your-currency',
    country_code: 'replace-with-your-country-code',
  });
  ```
 */
export declare const redirectToCheckout: (props: HostPaymentPage) => void | string;

/**
 * The definition that maps the Element type with its props options for customizing the Element.
 * We recommend `dropIn` element over `applePayButton`, `googlePayButton`, `wechat`, `qrcode`, `redirect` and `fullFeaturedCard` Elements as it allows the merchant to accept multiple payment methods in a single integration.
 */
export interface ElementOptionsTypeMap {
  /**
   * Define Card Number input Element type and its mapped option type. Applies to Split Card Element integration.
   * Use it together with `expiry` and `cvc` Elements to gain maximum customization.
   */
  cardNumber: CardNumberElementOptions;
  /**
   * Define Expiry input Element type and its mapped option type. Applies to Split Card Element integration.
   * Use it together with `cardNumber` and `cvc` Elements to gain maximum customization.
   */
  expiry: ExpiryDateElementOptions;
  /**
   * Define CVC input Element type and its mapped option type. Applies to Split Card Element integration.
   * Use it together with `cardNumber` and `expiry` Elements to gain maximum customization.
   */
  cvc: CvcElementOptions;
  /**
   * Define Apple Pay Element type and its mapped option type.
   */
  applePayButton: ApplePayButtonOptions;
  /**
   * Define Google Pay Element type and its mapped option type.
   */
  googlePayButton: GooglePayButtonOptions;
  /**
   * Define Card Element type and its mapped option type. This integration renders a single input for card PCI information (card number / cvc / expiry).
   */
  card: CardElementOptions;
  /**
   * Define WeChat Element type and its mapped option type.
   */
  wechat: WechatElementOptions;
  /**
   * Define Qrcode Element type and its mapped option type.
   */
  qrcode: QrcodeElementOptions;
  /**
   * Define Redirect Element type and its mapped option type.
   */
  redirect: RedirectElementOptions;
  /**
   * Define Drop-in Element type and its mapped option type. This integration renders a single widget for all supported payment methods.
   */
  dropIn: DropInElementOptions;
  /**
   * Define full featured card element type and its mapped option type. This integration renders a single widget for all card payment details.
   */
  fullFeaturedCard: FullFeaturedCardElementOptions;
}

export interface ElementTypeMap {
  cardNumber?: CardNumberElementType;
  expiry?: ExpiryDateElementType;
  cvc?: CvcElementType;
  applePayButton?: ApplePayButtonElementType;
  googlePayButton?: GooglePayButtonElementType;
  card?: CardElementType;
  dropIn?: DropInElementType;
  wechat?: WechatElementType;
  qrcode?: QrcodeElementType;
  redirect?: RedirectElementType;
  fullFeaturedCard?: FullFeaturedCardElementType;
}

/**
 * Interface of the request when confirmPaymentIntent() is called with contact.
 * This applies when you already have a Payment Consent created using createPaymentConsent() and your shopper would like to confirm the Payment Intent with the pre-signed consent (linked with customer_id).
 */
export interface PaymentMethodWithConsent {
  /**
   * The id of the intent which would be confirmed
   * @deprecated Use {@link intent_id} instead
   */
  id?: string;
  /**
   * The ID of the Payment Intent you would like to confirm.
   */
  intent_id: string;
  /**
   * The client_secret returned in the response when you create a Payment Intent.
   */
  client_secret: string;
  /**
   * The Element you would like to use to confirm the Payment Intent.
   */
  element: Element;
  /**
   * The ID of the Payment Consent referenced for this recurring payment.
   */
  payment_consent_id: string;
}

export interface Consent {
  /**
   * The ID of the Payment Consent to be confirmed.
   */
  id: string;
  /**
   * The `client_secret` returned when creating a Payment Consent.
   */
  client_secret: string;
  /**
   * The status of the Payment Consent.
   */
  status: 'PENDING_VERIFICATION' | 'VERIFIED' | 'DISABLED';
  /**
   * The time this Payment Consent was created.
   */
  created_at: string;
  /**
   * The time this Payment Consent was last updated.
   */
  updated_at: string;
  /**
   *  Whether the `merchant` or `customer` should trigger subsequent payments.
   */
  next_triggered_by: 'merchant' | 'customer';
  /**
   * Whether subsequent payments are `'scheduled'` or `'unscheduled'`. Only applicable when `next_triggered_by` is `'merchant'`.
   *
   * @defaultValue `'unscheduled'`
   */
  merchant_trigger_reason?: 'scheduled' | 'unscheduled';
  /**
   * The ID of the Customer who intends to pay for the Payment Intent.
   */
  customer_id: string;
  /**
   * The ID of the initial Payment Intent.
   */
  initial_payment_intent_id?: string;
}

/**
 * Element integration `step #2`
 * Create payment element for checkout
 * We recommend `dropIn` element over `applePayButton`, `googlePayButton`, `wechat`, `qrcode`, `redirect` and `fullFeaturedCard` Elements as it allows the merchant to accept multiple payment methods in a single integration.
 *
 */
export declare function createElement<T extends keyof ElementOptionsTypeMap>(
  type: T,
  options?: ElementOptionsTypeMap[T],
): ElementTypeMap[T] | null;
/**
 * Destroys the Element instance.
 */
export declare const destroyElement: (type: ElementType) => boolean;

/**
 * Query the created Element by type. Only one type of Element can be embedded in one page.
 */
export declare function getElement<T extends keyof ElementOptionsTypeMap>(type: T): ElementTypeMap[T] | null;

/**
 * Confirm the Payment Intent with Element and the other payment method details.
 * Only required for card payment method.
 *
 * `PaymentMethod`: The request payload for guest checkout without a Payment Consent.
 *
 * `PaymentMethodWithConsent`: The request payload for confirming a Payment Intent with a Payment Consent (created by `createPaymentConsent()` with an existing customer)
 */
export declare const confirmPaymentIntent: (
  data?: PaymentMethod | PaymentMethodWithConsent,
) => Promise<Intent | boolean>;

/**
 * Confirm a Payment Intent with a saved card and the other payment method information.
 * Only required for CVC Element.
 */
export declare const confirmPaymentIntentWithSavedCard: (data?: PaymentMethod) => Promise<Intent | boolean>;

/**
 * Function to create a payment method for future payments. The created payment method can be saved in your system.
 *
 */
export declare const createPaymentMethod: (
  client_secret: string,
  data: PaymentMethod,
) => Promise<PaymentMethodBasicInfo | boolean>;

/**
 * Function to get Payment Intent details from the browser side to directly query on the Airwallex API server.
 * Guarantee with fast query speed
 */
export declare const getPaymentIntent: (id: string, client_secret: string) => Promise<Intent | boolean>;

/**
 * Interface of the request when createPaymentConsent() is called.
 * @deprecated use `element.createPaymentConsent(data)` instead
 */
export interface PaymentConsentRequest {
  /**
   * The intent_id that would be confirmed with the new Payment Consent.
   */
  intent_id?: string;
  /**
   * The currency of the Payment Consent. Required for card Element type.
   */
  currency?: string;
  /**
   * The `client_secret` of the Payment Intent when Payment Intent is provided. Otherwise, this should be the `client_secret` of the Customer object.
   */
  client_secret?: string;
  /**
   * The Element you would like to use to create a Payment Consent.
   */
  element: Element;
  /**
   * The ID of the payment method. Required when you want to create a Payment Consent with a saved payment method.
   */
  payment_method_id?: string;
  /**
   * The ID of the Customer who intends to pay for the Payment Intent.
   */
  customer_id: string;
  /**
   * The cardholder name for this payment method.
   */
  cardname?: string;
  /**
   * Whether the `merchant` or `customer` should trigger subsequent payments.
   */
  next_triggered_by?: 'merchant' | 'customer';
  /**
   * Whether subsequent payments are `'scheduled'` or `'unscheduled'`. Only applicable when `next_triggered_by` is `'merchant'`.
   *
   * @defaultValue `'unscheduled'`
   */
  merchant_trigger_reason?: 'scheduled' | 'unscheduled';
  /**
   * The billing info for the Payment Consent.
   */
  billing?: Billing;
  /**
   * The ID of the connected account linked to the platform.
   * The platform should indicate the connected entity in the transaction only when platform is the owner of the transaction.
   */
  connected_account_id?: string;
  /**
   * A set of key-value pairs that can be attached to this Payment Consent.
   */
  metadata?: Record<string, unknown>;
  /**
   *  Set it to `true` if you want to skip 3DS regardless of the risk score and SCA. Only applicable to card recurring payments.
   */
  skip_3ds?: boolean;
}

/**
 * Interface of the data when `element.createPaymentConsent(data)` is called.
 */
export interface PaymentConsentRequestData {
  /**
   * The intent_id that would be confirmed with the new Payment Consent.
   */
  intent_id?: string;
  /**
   * The currency of the Payment Consent. Required for card Element type.
   */
  currency?: string;
  /**
   * The `client_secret` of the Payment Intent when Payment Intent is provided. Otherwise, this should be the `client_secret` of the Customer object.
   */
  client_secret: string;
  /**
   * The ID of the payment method. Required when you want to create a Payment Consent with a saved payment method.
   */
  payment_method_id?: string;
  /**
   * The ID of the Customer who intends to pay for the Payment Intent.
   */
  customer_id?: string;
  /**
   * The cardholder name for this payment method.
   */
  cardname?: string;
  /**
   * Whether the merchant or customer should trigger subsequent payments.
   * @defaultValue `'customer'`
   */
  next_triggered_by?: 'merchant' | 'customer';
  /**
   * Whether subsequent payments are `'scheduled'` or `'unscheduled'`. Only applicable when `next_triggered_by` is `'merchant'`.
   *
   * @defaultValue `'unscheduled'`
   */
  merchant_trigger_reason?: 'scheduled' | 'unscheduled';
  /**
   * The billing info for the Payment Consent.
   */
  billing?: Billing;
  /**
   * The ID of the connected account linked to the platform.
   * The platform should indicate the connected entity in the transaction only when platform is the owner of the transaction.
   */
  connected_account_id?: string;
  /**
   * A set of key-value pairs that can be attached to this Payment Consent.
   */
  metadata?: Record<string, unknown>;
  /**
   *  Set it to `true` if you want to skip 3DS regardless of the risk score and Strong Customer Authentication (SCA) regulation. Only applicable when it's a card recurring flow.
   * @deprecated use {@link threeDsAction} instead
   * @hidden
   */
  skip_3ds?: boolean;
  /**
   *  Set it to `SKIP_3DS` if you want to skip 3DS regardless of the risk score and Strong Customer Authentication (SCA) regulation. Only applicable when it's a card recurring flow.
   *  Set it to `FORCE_3DS` if you want to force 3DS regardless of the risk score and Strong Customer Authentication (SCA) regulation. Only applicable when it's a card recurring flow.
   */
  three_ds_action?: 'SKIP_3DS' | 'FORCE_3DS';
}

/**
 * Interface of the request when call verifyConsent
 */
export interface VerifyConsentRequest {
  /**
   * The currency of the payment consent, if you are creating card consent, currency is required
   */
  currency: string;
  /**
   * This should be the client_secret of the consent
   */
  client_secret: string;
}

/**
 * Interface of the data when `element.createPaymentMethod(data)` is called.
 */
export interface CreatePaymentMethodRequest {
  /**
   * The `client_secret` of the Payment Intent when Payment Intent is provided. Otherwise, this should be the `client_secret` of the Customer object.
   */
  client_secret: string;
  /**
   * The ID of the Customer who intends to pay for the Payment Intent.
   */
  customer_id?: string;
  /**
   * A set of key-value pairs that can be attached to this Payment Consent.
   */
  metadata?: Record<string, unknown>;
  /**
   * The payment method details returned by calling createPaymentMethod().
   */
  payment_method?: PaymentMethodObjType;
}

/**
 * Interface of the response payload when call createPaymentConsent or verifyConsent
 * Interface of the response payload when createPaymentConsent() is called.
 */
export interface PaymentConsentResponse {
  /**
   * Returns `intent_id` if merchant provides `intent_id` in createPaymentConsent(). Otherwise, Airwallex creates an initial Payment Intent and returns the `intent_id.`
   */
  intent_id?: string;
  /**
   * The ID of the new Payment Consent.
   */
  payment_consent_id: string;
  /**
   * The ID of the Customer who intends to pay for the Payment Intent.
   */
  customer_id: string;
  /**
   * The currency of the Payment Consent.
   */
  currency?: string;
  /**
   * The payment method of the Payment Consent.
   */
  payment_method?: {
    /**
     * The ID of the payment method.
     */
    id: string;
    /**
     * The card BIN.
     */
    bin?: string;
    /**
     * The last 4 digits of the card.
     */
    last4?: string;
    /**
     * The card brand.
     */
    brand?: string;
  };
}

/**
 * Interface for recurring consent payment, use this interface to create payment consent with element integration
 */
export declare const createPaymentConsent: (data: PaymentConsentRequest) => Promise<PaymentConsentResponse | boolean>;

/**
 * Interface of global const can be used directly in browser javascript
 */
export interface Airwallex {
  init: typeof init;
  redirectToCheckout: typeof redirectToCheckout;
  createElement: typeof createElement;
  destroyElement: typeof destroyElement;
  getElement: typeof getElement;
  confirmPaymentIntent: typeof confirmPaymentIntent;
  confirmPaymentIntentWithSavedCard: typeof confirmPaymentIntentWithSavedCard;
  createPaymentMethod: typeof createPaymentMethod;
  createPaymentConsent: typeof createPaymentConsent;
  getPaymentIntent: typeof getPaymentIntent;
  getDeviceFingerprint: typeof getDeviceFingerprint;
}

export default Airwallex;
