import { Platform } from 'react-native';
import { NativeModulesProxy } from '@unimodules/core';
import processTheme from './utils/processTheme';
import checkArgs from './utils/checkArgs';
import checkInit from './utils/checkInit';
import * as types from './utils/types';
import errorCodes from './errorCodes';

const { StripeModule } = NativeModulesProxy;

class Stripe {
  stripeInitialized = false;

  setOptionsAsync = (options = {}) => {
    checkArgs(types.setOptionsOptionsPropTypes, options, 'options', 'Stripe.setOptions');

    this.stripeInitialized = true;

    return StripeModule.init(options, errorCodes);
  };

  // @deprecated use deviceSupportsNativePay
  deviceSupportsAndroidPayAsync = () => StripeModule.deviceSupportsAndroidPay();

  // @deprecated use deviceSupportsNativePay
  deviceSupportsApplePayAsync = () => StripeModule.deviceSupportsApplePay();

  deviceSupportsNativePayAsync = () =>
    Platform.select({
      ios: () => this.deviceSupportsApplePay(),
      android: () => this.deviceSupportsAndroidPay(),
    })();

  // @deprecated use canMakeNativePayPayments
  canMakeApplePayPaymentsAsync = (options = {}) => {
    checkArgs(
      types.canMakeApplePayPaymentsOptionsPropTypes,
      options,
      'options',
      'Stripe.canMakeApplePayPayments'
    );
    return StripeModule.canMakeApplePayPayments(options);
  };

  // @deprecated use canMakeNativePayPayments
  canMakeAndroidPayPaymentsAsync = () => StripeModule.canMakeAndroidPayPayments();

  // iOS requires networks array while Android requires nothing
  canMakeNativePayPaymentsAsync = (options = {}) =>
    Platform.select({
      ios: () => this.canMakeApplePayPayments(options),
      android: () => this.canMakeAndroidPayPayments(),
    })();

  // @deprecated use paymentRequestWithNativePay
  paymentRequestWithAndroidPayAsync = (options = {}) => {
    checkInit(this);
    checkArgs(
      types.paymentRequestWithAndroidPayOptionsPropTypes,
      options,
      'options',
      'Stripe.paymentRequestWithAndroidPay'
    );
    return StripeModule.paymentRequestWithAndroidPay(options);
  };

  // @deprecated use paymentRequestWithNativePay
  paymentRequestWithApplePayAsync = (items = [], options = {}) => {
    checkInit(this);
    checkArgs(
      types.paymentRequestWithApplePayItemsPropTypes,
      { items },
      'items',
      'Stripe.paymentRequestWithApplePay'
    );
    checkArgs(
      types.paymentRequestWithApplePayOptionsPropTypes,
      options,
      'options',
      'Stripe.paymentRequestWithApplePay'
    );
    return StripeModule.paymentRequestWithApplePay(items, options);
  };

  paymentRequestWithNativePayAsync(options = {}, items = []) {
    return Platform.select({
      ios: () => this.paymentRequestWithApplePay(items, options),
      android: () => this.paymentRequestWithAndroidPay(options),
    })();
  }

  // @deprecated use completeNativePayRequest
  completeApplePayRequestAsync = () => {
    checkInit(this);
    return StripeModule.completeApplePayRequest();
  };

  // no corresponding android impl exists
  completeNativePayRequestAsync = () =>
    Platform.select({
      ios: () => this.completeApplePayRequest(),
      android: () => Promise.resolve(),
    })();

  // @deprecated use cancelNativePayRequest
  cancelApplePayRequestAsync = () => {
    checkInit(this);
    return StripeModule.cancelApplePayRequest();
  };

  // no corresponding android impl exists
  cancelNativePayRequestAsync = () =>
    Platform.select({
      ios: () => this.cancelApplePayRequest(),
      android: () => Promise.resolve(),
    })();

  // @deprecated use openNativePaySetup
  openApplePaySetupAsync = () => StripeModule.openApplePaySetup();

  // no corresponding android impl exists
  openNativePaySetupAsync = () =>
    Platform.select({
      ios: () => this.openApplePaySetup(),
      android: () => Promise.resolve(),
    })();

  paymentRequestWithCardFormAsync = (options = {}) => {
    checkInit(this);
    checkArgs(
      types.paymentRequestWithCardFormOptionsPropTypes,
      options,
      'options',
      'Stripe.paymentRequestWithCardForm'
    );
    return StripeModule.paymentRequestWithCardForm({
      ...options,
      theme: processTheme(options.theme),
    });
  };

  createTokenWithCardAsync = (params = {}) => {
    checkInit(this);
    checkArgs(
      types.createTokenWithCardParamsPropTypes,
      params,
      'params',
      'Stripe.createTokenWithCard'
    );
    return StripeModule.createTokenWithCard(params);
  };

  createTokenWithBankAccountAsync = (params = {}) => {
    checkInit(this);
    checkArgs(
      types.createTokenWithBankAccountParamsPropTypes,
      params,
      'params',
      'Stripe.createTokenWithBankAccount'
    );
    return StripeModule.createTokenWithBankAccount(params);
  };

  createSourceWithParamsAsync = (params = {}) => {
    checkInit(this);
    checkArgs(
      types.createSourceWithParamsPropType,
      params,
      'params',
      'Stripe.createSourceWithParams'
    );
    return StripeModule.createSourceWithParams(params);
  };
}

export default new Stripe();

@@ -974,16 +974,21 @@
 ApplePay
+Async
 (),%0A    
@@ -1033,16 +1033,21 @@
 droidPay
+Async
 (),%0A    
@@ -1667,32 +1667,37 @@
 ApplePayPayments
+Async
 (options),%0A     
@@ -1742,16 +1742,21 @@
 Payments
+Async
 (),%0A    
@@ -2761,32 +2761,37 @@
 uestWithApplePay
+Async
 (items, options)
@@ -2838,32 +2838,37 @@
 stWithAndroidPay
+Async
 (options),%0A    %7D
@@ -3183,32 +3183,37 @@
 eApplePayRequest
+Async
 (),%0A      androi
@@ -3392,32 +3392,37 @@
 lApplePayRequest
+Async
 ();%0A  %7D;%0A%0A  // n
@@ -3560,16 +3560,21 @@
 yRequest
+Async
 (),%0A    
@@ -3818,32 +3818,32 @@
 atform.select(%7B%0A
-
       ios: () =%3E
@@ -3865,16 +3865,21 @@
 PaySetup
+Async
 (),%0A    

Fix wrong method names