'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const index = require('./index-9c866aeb.js');
const pure = require('./pure-9921b66f.js');
const defaultI18n = require('./default-i18n-d4248548.js');
require('./index-88baf240.js');
const consumer = require('./consumer-3f5ce850.js');
const index$1 = require('./index-9e90cef7.js');
require('./index-04dc658f.js');
require('./watchers-203d7acd.js');
require('./index-f6f80680.js');
require('./add-query-args-17c551b6.js');
require('./watchers-ca60947e.js');
require('./watchers-d5742848.js');
require('./getters-24bb377c.js');
require('./util-872b1a55.js');
require('./fetch-02d6cb7b.js');
require('./get-query-arg-53bf21e2.js');

const scStripePaymentRequestCss = ":host{display:block}.or{display:none;margin:var(--sc-form-section-spacing) 0}.request--loaded .or{display:block}";

const ScStripePaymentRequest = class {
  constructor(hostRef) {
    index.registerInstance(this, hostRef);
    this.scFormSubmit = index.createEvent(this, "scFormSubmit", 7);
    this.scPaid = index.createEvent(this, "scPaid", 7);
    this.scPayError = index.createEvent(this, "scPayError", 7);
    this.scSetState = index.createEvent(this, "scSetState", 7);
    this.scPaymentRequestLoaded = index.createEvent(this, "scPaymentRequestLoaded", 7);
    this.scUpdateOrderState = index.createEvent(this, "scUpdateOrderState", 7);
    /** Country */
    this.country = 'US';
    /** Currency */
    this.currencyCode = 'usd';
    /** Label */
    this.label = 'total';
    /** Amount */
    this.amount = 0;
    /** Payment request theme */
    this.theme = 'dark';
    /** Is this in debug mode. */
    this.debug = false;
    /** Has this loaded */
    this.loaded = false;
  }
  async componentWillLoad() {
    if (!(this === null || this === void 0 ? void 0 : this.publishableKey) || !(this === null || this === void 0 ? void 0 : this.stripeAccountId)) {
      return true;
    }
    try {
      this.stripe = await pure.pure.loadStripe(this.publishableKey, { stripeAccount: this.stripeAccountId });
      this.elements = this.stripe.elements();
      this.paymentRequest = this.stripe.paymentRequest({
        country: this.country,
        requestShipping: true,
        requestPayerEmail: true,
        shippingOptions: [
          {
            id: 'free',
            label: 'Free Shipping',
            detail: 'No shipping required',
            amount: 0,
          },
        ],
        ...this.getRequestObject(this.order),
      });
    }
    catch (e) {
      console.log((e === null || e === void 0 ? void 0 : e.message) || defaultI18n.__('Stripe could not be loaded', 'surecart'));
    }
  }
  handleOrderChange() {
    if (!this.paymentRequest)
      return;
    if (this.pendingEvent)
      return;
    this.paymentRequest.update(this.getRequestObject(this.order));
  }
  handleLoaded() {
    this.scPaymentRequestLoaded.emit(true);
  }
  handleErrorChange() {
    if (this.pendingEvent) {
      this.pendingEvent.complete('error');
    }
  }
  async handleShippingChange(ev) {
    var _a, _b, _c, _d, _e;
    const { shippingAddress, updateWith } = ev;
    try {
      const order = (await index$1.createOrUpdateCheckout({
        id: (_a = this.order) === null || _a === void 0 ? void 0 : _a.id,
        data: {
          shipping_address: {
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.name) ? { name: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.name } : {}),
            ...(((_b = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _b === void 0 ? void 0 : _b[0]) ? { line_1: (_c = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _c === void 0 ? void 0 : _c[0] } : {}),
            ...(((_d = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _d === void 0 ? void 0 : _d[1]) ? { line_2: (_e = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _e === void 0 ? void 0 : _e[1] } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.city) ? { city: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.city } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.country) ? { country: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.country } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.postalCode) ? { postal_code: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.postalCode } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.region) ? { state: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.region } : {}),
          },
        },
      }));
      updateWith({
        status: 'success',
        total: {
          amount: (order === null || order === void 0 ? void 0 : order.amount_due) || 0,
          label: defaultI18n.__('Total', 'surecart'),
          pending: true,
        },
      });
    }
    catch (e) {
      e.updateWith({ status: 'invalid_shipping_address' });
    }
  }
  /** Only append price name if there's more than one product price in the session. */
  getName(item) {
    var _a, _b, _c, _d, _e;
    const otherPrices = Object.keys(this.prices || {}).filter(key => {
      const price = this.prices[key];
      // @ts-ignore
      return price.product === item.price.product.id;
    });
    let name = '';
    if (otherPrices.length > 1) {
      name = `${(_b = (_a = item === null || item === void 0 ? void 0 : item.price) === null || _a === void 0 ? void 0 : _a.product) === null || _b === void 0 ? void 0 : _b.name} \u2013 ${(_c = item === null || item === void 0 ? void 0 : item.price) === null || _c === void 0 ? void 0 : _c.name}`;
    }
    else {
      name = (_e = (_d = item === null || item === void 0 ? void 0 : item.price) === null || _d === void 0 ? void 0 : _d.product) === null || _e === void 0 ? void 0 : _e.name;
    }
    return name;
  }
  getRequestObject(order) {
    var _a;
    const displayItems = (((_a = order === null || order === void 0 ? void 0 : order.line_items) === null || _a === void 0 ? void 0 : _a.data) || []).map(item => {
      return {
        label: this.getName(item),
        amount: item.ad_hoc_amount !== null ? item.ad_hoc_amount : item.subtotal_amount,
      };
    });
    return {
      currency: this.currencyCode,
      total: {
        amount: (order === null || order === void 0 ? void 0 : order.amount_due) || 0,
        label: defaultI18n.__('Total', 'surecart'),
        pending: true,
      },
      displayItems,
    };
  }
  componentDidLoad() {
    if (!this.elements) {
      return;
    }
    const paymentRequestElement = this.elements.create('paymentRequestButton', {
      paymentRequest: this.paymentRequest,
      style: {
        paymentRequestButton: {
          theme: this.theme,
        },
      },
    });
    // handle payment method.
    this.paymentRequest.on('paymentmethod', e => this.handlePaymentMethod(e));
    this.paymentRequest.on('shippingaddresschange', async (ev) => await this.handleShippingChange(ev));
    // mount button.
    this.paymentRequest
      .canMakePayment()
      .then(result => {
      if (!result) {
        if (location.protocol !== 'https:') {
          if (this.debug) {
            this.debugError = defaultI18n.__('You must serve this page over HTTPS to display express payment buttons.', 'surecart');
          }
          console.log('SSL needed to display payment buttons.');
        }
        else {
          if (this.debug) {
            this.debugError = defaultI18n.__('You do not have any wallets set up in your browser.', 'surecart');
          }
          console.log('No wallets available.');
        }
        return;
      }
      paymentRequestElement.mount(this.request);
      this.loaded = true;
    })
      .catch(e => {
      console.error(e);
    });
  }
  /** Handle the payment method. */
  async handlePaymentMethod(ev) {
    var _a, _b, _c, _d, _e;
    const { billing_details } = ev === null || ev === void 0 ? void 0 : ev.paymentMethod;
    const { shippingAddress } = ev;
    try {
      this.scSetState.emit('FINALIZE');
      // update session with shipping/billing
      (await index$1.createOrUpdateCheckout({
        id: (_a = this.order) === null || _a === void 0 ? void 0 : _a.id,
        data: {
          email: billing_details === null || billing_details === void 0 ? void 0 : billing_details.email,
          name: billing_details === null || billing_details === void 0 ? void 0 : billing_details.name,
          shipping_address: {
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.name) ? { name: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.name } : {}),
            ...(((_b = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _b === void 0 ? void 0 : _b[0]) ? { line_1: (_c = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _c === void 0 ? void 0 : _c[0] } : {}),
            ...(((_d = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _d === void 0 ? void 0 : _d[1]) ? { line_2: (_e = shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.addressLine) === null || _e === void 0 ? void 0 : _e[1] } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.city) ? { city: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.city } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.country) ? { country: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.country } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.postalCode) ? { postal_code: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.postalCode } : {}),
            ...((shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.region) ? { state: shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.region } : {}),
          },
        },
      }));
      // finalize
      const session = (await index$1.finalizeCheckout({
        id: this.order.id,
        query: {
          form_id: this.formId,
        },
        processor: { id: 'stripe', manual: false },
      }));
      // confirm payment
      this.scSetState.emit('PAYING');
      await this.confirmPayment(session, ev);
      this.scSetState.emit('PAID');
      // paid.
      this.scPaid.emit();
      // Report to the browser that the confirmation was successful, prompting
      // it to close the browser payment method collection interface.
      ev.complete('success');
    }
    catch (e) {
      console.error(e);
      this.scPayError.emit(e);
      ev.complete('fail');
    }
    finally {
      this.confirming = false;
    }
  }
  async confirmPayment(val, ev) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
    // must be finalized
    if ((val === null || val === void 0 ? void 0 : val.status) !== 'finalized')
      return;
    // must have a secret
    if (!((_c = (_b = (_a = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _a === void 0 ? void 0 : _a.processor_data) === null || _b === void 0 ? void 0 : _b.stripe) === null || _c === void 0 ? void 0 : _c.client_secret))
      return;
    // need an external_type
    if (!((_f = (_e = (_d = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _d === void 0 ? void 0 : _d.processor_data) === null || _e === void 0 ? void 0 : _e.stripe) === null || _f === void 0 ? void 0 : _f.type))
      return;
    // must have an external intent id
    if (!((_g = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _g === void 0 ? void 0 : _g.external_intent_id))
      return;
    // prevent possible double-charges
    if (this.confirming)
      return;
    this.confirming = true;
    let response;
    if (((_k = (_j = (_h = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _h === void 0 ? void 0 : _h.processor_data) === null || _j === void 0 ? void 0 : _j.stripe) === null || _k === void 0 ? void 0 : _k.type) == 'setup') {
      response = await this.confirmCardSetup((_m = (_l = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _l === void 0 ? void 0 : _l.processor_data) === null || _m === void 0 ? void 0 : _m.stripe.client_secret, ev);
    }
    else {
      response = await this.confirmCardPayment((_p = (_o = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _o === void 0 ? void 0 : _o.processor_data) === null || _p === void 0 ? void 0 : _p.stripe.client_secret, ev);
    }
    if (response === null || response === void 0 ? void 0 : response.error) {
      throw response.error;
    }
    // Check if the PaymentIntent requires any actions and if so let Stripe.js
    // handle the flow. If using an API version older than "2019-02-11"
    // instead check for: `paymentIntent.status === "requires_source_action"`.
    if (((_q = response === null || response === void 0 ? void 0 : response.paymentIntent) === null || _q === void 0 ? void 0 : _q.status) === 'requires_action' || ((_r = response === null || response === void 0 ? void 0 : response.paymentIntent) === null || _r === void 0 ? void 0 : _r.status) === 'requires_source_action') {
      // Let Stripe.js handle the rest of the payment flow.
      const result = await this.stripe.confirmCardPayment((_t = (_s = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _s === void 0 ? void 0 : _s.processor_data) === null || _t === void 0 ? void 0 : _t.stripe.client_secret);
      // The payment failed -- ask your customer for a new payment method.
      if (result.error) {
        throw result.error;
      }
      return result;
    }
    return response;
  }
  /** Confirm card payment. */
  confirmCardPayment(secret, ev) {
    return this.stripe.confirmCardPayment(secret, { payment_method: ev.paymentMethod.id }, { handleActions: false });
  }
  /** Confirm card setup. */
  confirmCardSetup(secret, ev) {
    return this.stripe.confirmCardSetup(secret, { payment_method: ev.paymentMethod.id }, { handleActions: false });
  }
  render() {
    return (index.h("div", { class: { 'request': true, 'request--loaded': this.loaded } }, this.debug && this.debugError && (index.h("div", null, index.h("slot", { name: "debug-fallback" }), index.h("sc-alert", { type: "info", open: true }, index.h("span", { slot: "title" }, defaultI18n.__('Express Payment', 'surecart')), this.debugError))), index.h("div", { class: "sc-payment-request-button", part: "button", ref: el => (this.request = el) })));
  }
  get el() { return index.getElement(this); }
  static get watchers() { return {
    "order": ["handleOrderChange"],
    "loaded": ["handleLoaded"],
    "error": ["handleErrorChange"]
  }; }
};
consumer.openWormhole(ScStripePaymentRequest, ['currencyCode', 'country', 'prices', 'paymentMethod'], false);
ScStripePaymentRequest.style = scStripePaymentRequestCss;

exports.sc_stripe_payment_request = ScStripePaymentRequest;
