import { Component, Element, Event, h, Method, Prop, State, Watch } from '@stencil/core';
import { loadStripe } from '@stripe/stripe-js/pure';
export class ScStripePaymentElement {
  constructor() {
    /** Is this yet loaded. */
    this.loaded = false;
    /** Are we confirming the order? */
    this.confirming = false;
  }
  /** Maybe load the stripe element on load. */
  async componentDidLoad() {
    if (!this.publishableKey || !this.accountId)
      return;
    this.stripe = await loadStripe(this.publishableKey, { stripeAccount: this.accountId });
    this.loadElement();
  }
  /** Reload element if client secret changes. */
  handleClientSecretChange(val, prev) {
    if (val !== prev) {
      this.loaded = false;
      this.loadElement();
    }
  }
  /**
   * Watch order status and maybe confirm the order.
   */
  async maybeConfirmOrder(val) {
    var _a, _b, _c, _d, _e, _f, _g;
    // must be finalized
    if ((val === null || val === void 0 ? void 0 : val.status) !== 'finalized')
      return;
    // must be a stripe session
    if (((_a = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _a === void 0 ? void 0 : _a.processor_type) !== 'stripe')
      return;
    // need an external_type
    if (!((_d = (_c = (_b = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _b === void 0 ? void 0 : _b.processor_data) === null || _c === void 0 ? void 0 : _c.stripe) === null || _d === void 0 ? void 0 : _d.type))
      return;
    // confirm the intent.
    return await this.confirm((_g = (_f = (_e = val === null || val === void 0 ? void 0 : val.payment_intent) === null || _e === void 0 ? void 0 : _e.processor_data) === null || _f === void 0 ? void 0 : _f.stripe) === null || _g === void 0 ? void 0 : _g.type);
  }
  async confirm(type, args = {}) {
    const confirmArgs = {
      elements: this.elements,
      confirmParams: {
        return_url: this.successUrl,
      },
      redirect: 'if_required',
      ...args,
    };
    // prevent possible double-charges
    if (this.confirming)
      return;
    try {
      const response = type === 'setup' ? await this.stripe.confirmSetup(confirmArgs) : await this.stripe.confirmPayment(confirmArgs);
      if (response === null || response === void 0 ? void 0 : response.error) {
        this.error = response.error.message;
        throw response.error;
      }
      // paid
      this.scPaid.emit();
    }
    catch (e) {
      console.error(e);
      this.scPayError.emit(e);
      if (e.message) {
        this.error = e.message;
      }
    }
    finally {
      this.confirming = false;
    }
  }
  loadElement() {
    // we need a stripe instance and client secret.
    if (!this.stripe || !this.clientSecret || !this.container) {
      return;
    }
    // get the computed styles.
    const styles = getComputedStyle(document.body);
    // we have what we need, load elements.
    this.elements = this.stripe.elements({
      clientSecret: this.clientSecret,
      appearance: {
        variables: {
          colorPrimary: styles.getPropertyValue('--sc-color-primary-500'),
          colorText: styles.getPropertyValue('--sc-input-label-color'),
          borderRadius: styles.getPropertyValue('--sc-input-border-radius-medium'),
          colorBackground: styles.getPropertyValue('--sc-input-background-color'),
          fontSizeBase: styles.getPropertyValue('--sc-input-font-size-medium'),
        },
        rules: {
          '.Input': {
            border: styles.getPropertyValue('--sc-input-border'),
          },
          '.Input::placeholder': {
            color: styles.getPropertyValue('--sc-input-placeholder-color'),
          },
        },
      },
    });
    // create the payment element.
    this.elements
      .create('payment', {
      wallets: {
        applePay: 'never',
        googlePay: 'never',
      },
    })
      .mount('.sc-payment-element-container');
    this.element = this.elements.getElement('payment');
    this.element.on('ready', () => (this.loaded = true));
  }
  render() {
    return (h("div", { class: "sc-stripe-payment-element", "data-testid": "stripe-payment-element" },
      !!this.error && (h("sc-text", { style: {
          'color': 'var(--sc-color-danger-500)',
          '--font-size': 'var(--sc-font-size-small)',
          'marginBottom': '0.5em',
        } }, this.error)),
      h("div", { class: "loader", hidden: this.loaded },
        h("div", { class: "loader__row" },
          h("div", { style: { width: '50%' } },
            h("sc-skeleton", { style: { width: '50%', marginBottom: '0.5em' } }),
            h("sc-skeleton", null)),
          h("div", { style: { flex: '1' } },
            h("sc-skeleton", { style: { width: '50%', marginBottom: '0.5em' } }),
            h("sc-skeleton", null)),
          h("div", { style: { flex: '1' } },
            h("sc-skeleton", { style: { width: '50%', marginBottom: '0.5em' } }),
            h("sc-skeleton", null))),
        h("div", { class: "loader__details" },
          h("sc-skeleton", { style: { height: '1rem' } }),
          h("sc-skeleton", { style: { height: '1rem', width: '30%' } }))),
      h("div", { hidden: !this.loaded, class: "sc-payment-element-container", ref: el => (this.container = el) })));
  }
  static get is() { return "sc-stripe-payment-element"; }
  static get originalStyleUrls() { return {
    "$": ["sc-stripe-payment-element.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["sc-stripe-payment-element.css"]
  }; }
  static get properties() { return {
    "clientSecret": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The client secret to render the payment element"
      },
      "attribute": "client-secret",
      "reflect": false
    },
    "publishableKey": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The stripe publishable key."
      },
      "attribute": "publishable-key",
      "reflect": false
    },
    "accountId": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The account id."
      },
      "attribute": "account-id",
      "reflect": false
    },
    "order": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "Order | Invoice",
        "resolved": "Invoice | Order",
        "references": {
          "Order": {
            "location": "import",
            "path": "../../../types"
          },
          "Invoice": {
            "location": "import",
            "path": "../../../types"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Order to watch"
      }
    },
    "address": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Should we collect an address?"
      },
      "attribute": "address",
      "reflect": false
    },
    "successUrl": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Success url to redirect."
      },
      "attribute": "success-url",
      "reflect": false
    }
  }; }
  static get states() { return {
    "error": {},
    "loaded": {},
    "confirming": {}
  }; }
  static get events() { return [{
      "method": "scPaid",
      "name": "scPaid",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "The order/invoice was paid for."
      },
      "complexType": {
        "original": "void",
        "resolved": "void",
        "references": {}
      }
    }, {
      "method": "scPayError",
      "name": "scPayError",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "There was a payment error."
      },
      "complexType": {
        "original": "any",
        "resolved": "any",
        "references": {}
      }
    }]; }
  static get methods() { return {
    "confirm": {
      "complexType": {
        "signature": "(type: any, args?: {}) => Promise<void>",
        "parameters": [{
            "tags": [],
            "text": ""
          }, {
            "tags": [],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    }
  }; }
  static get elementRef() { return "el"; }
  static get watchers() { return [{
      "propName": "clientSecret",
      "methodName": "handleClientSecretChange"
    }, {
      "propName": "order",
      "methodName": "maybeConfirmOrder"
    }]; }
}
