function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
 * Copyright (c) 2022 International Business Group, Ant Group. All rights reserved.
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), the rights to use, copy, modify, merge, and/or distribute the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 1. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE; and
 * 2. If applicable, the use of the Software is also subject to the terms and conditions of any non-disclosure agreement signed by you and the relevant Ant Group entity.
 */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { BASEPLUGINID, ERRORMESSAGE, EVENT } from "../../constant";
import { MessageName } from "../../types";
import { getOrigin, getType, getViewPort, isDom, isJsonString, serialize } from "../../util";
var getServerPath = function getServerPath() {
  var _environment = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'prod';
  var version = arguments.length > 1 ? arguments[1] : undefined;
  var host = '';
  switch (_environment) {
    case 'dev':
      host = "http://page.alipay.net/page/antom-web-checkout/src/drop-in-app/index.".concat(version, ".html");
      break;
    case 'sandbox':
      host = "https://pre.ac.alipay.com/page/antom-web-checkout/src/drop-in-app/index.".concat(version, ".html");
      break;
    case 'prod':
      host = "https://ac.alipay.com/page/antom-web-checkout/src/drop-in-app/index.".concat(version, ".html");
      break;
    default:
      host = "https://ac.alipay.com/page/antom-web-checkout/src/drop-in-app/index.".concat(version, ".html");
      break;
  }
  return host;
};
var getServerHost = function getServerHost(_environment, version) {
  var reg = /^https?:\/\/([^/<>\s]+\.?)*/;
  var macth = reg.exec(getServerPath(_environment, version));
  return macth && macth[0] || '';
};
var CheckoutApp = /*#__PURE__*/function () {
  function CheckoutApp() {
    _classCallCheck(this, CheckoutApp);
    _defineProperty(this, "app", void 0);
    _defineProperty(this, "paymentMethodsResult", void 0);
    _defineProperty(this, "appDomain", void 0);
    _defineProperty(this, "AMSSDK", void 0);
    _defineProperty(this, "_render", void 0);
    _defineProperty(this, "_selector", void 0);
    _defineProperty(this, "_version", void 0);
    this._version = '1.0.0';
    this._render = function () {
      return Promise.resolve();
    };
  }
  /**
   * @description When SDK registers plug-ins, it is a required function to receive SDK instances
   */
  _createClass(CheckoutApp, [{
    key: "applyPlugin",
    value: function applyPlugin(AMSSDK) {
      this.AMSSDK = AMSSDK;
      this._subscribeFromSDK();
      // Subscribe to messages from iframe
      this._addEventListener();
      this.appDomain = getServerHost(this.AMSSDK.options.env.environment, this._version);
      this.app = this._createApp();
    }
    /**
     * @description Set the rendering capability of the cashier plug-in. Different technology stacks have some differences in the packaging and use of rendering functions
     */
  }, {
    key: "setRender",
    value: function setRender(createIframeNode) {
      this._render = createIframeNode;
    }
    /**
     * @description High order function of rendering capability
     */
  }, {
    key: "render",
    value: function render(renderParams) {
      this.paymentMethodsResult = renderParams.paymentMethodsResult;
      this._selector = renderParams.selector;
      this.app.src = this._getIframeUrl((renderParams === null || renderParams === void 0 ? void 0 : renderParams.appearance) || {});
      return this._render(this, {
        selector: renderParams.selector
      });
    }
    /**
     * @description Cancel listening and destroy the dom
     */
  }, {
    key: "logoutPlugin",
    value: function logoutPlugin() {
      try {
        this.app = null;
        this._removeEventListener();
        var dorpinDom = null;
        if (getType(this._selector) === 'string') {
          dorpinDom = document.querySelector(this._selector);
        }
        if (isDom(this._selector)) {
          dorpinDom = this._selector;
        }
        if (dorpinDom) dorpinDom.innerHTML = '';
        // eslint-disable-next-line no-empty
      } catch (error) {}
    }
    /**
     * @description Create app
     */
  }, {
    key: "_createApp",
    value: function _createApp() {
      var iframe;
      try {
        iframe = this._createIframe();
      } catch (error) {
        this._dispatchToSDK({
          name: MessageName.APP_TO_SDK,
          instanceId: this.AMSSDK._instanceId,
          context: {
            event: 'onError',
            data: Object.assign({}, ERRORMESSAGE.SDK_COMPATIBILITY_ISSUES.FAILED_TO_CREATE_IFRAME, {
              stack: error
            })
          }
        });
        return;
      }
      if (!!window.postMessage !== true) {
        this._dispatchToSDK({
          name: MessageName.APP_TO_SDK,
          instanceId: this.AMSSDK._instanceId,
          context: {
            event: 'onError',
            data: ERRORMESSAGE.SDK_COMPATIBILITY_ISSUES.BROWSER_NOT_SUPPORT_POSTMESSAGE
          }
        });
        return;
      }
      return iframe;
    }
  }, {
    key: "_getIframeUrl",
    value: function _getIframeUrl(appearance) {
      var path = getServerPath(this.AMSSDK.options.env.environment, this._version);
      var scale = getViewPort('initial-scale') || 1;
      var instanceId = this.AMSSDK._instanceId;
      var urlParams = Object.assign({
        locale: this.AMSSDK.options.locale,
        scale: scale,
        merchantDomain: window.btoa(getOrigin()),
        instanceId: instanceId
      }, appearance);
      var locationSearch = serialize(urlParams);
      return "".concat(path, "?").concat(locationSearch);
    }
    /**
     * @description Create iframe
     */
  }, {
    key: "_createIframe",
    value: function _createIframe() {
      var iframe = document.createElement('iframe');
      var iframeId = this._getIframeId(this.AMSSDK.options.mode);
      iframe.id = iframeId;
      iframe.style.height = '100%';
      iframe.style.width = '100%';
      iframe.style.border = '0';
      iframe.style.overflow = 'hidden';
      return iframe;
    }
    /**
     * @description Get iftame id
     */
  }, {
    key: "_getIframeId",
    value: function _getIframeId(UIMode) {
      var id = 'checkout-dropin';
      switch (UIMode) {
        case 'DROPIN':
          id = 'checkout-dropin';
          break;
        case 'COMPONENT':
          id = 'ams-checkout-component';
          break;
      }
      return id;
    }
  }, {
    key: "_listener",
    value: function _listener(e) {
      if (e.origin !== this.appDomain) {
        return;
      }
      var isJson = isJsonString(e.data);
      if (isJson) {
        var data = JSON.parse(e.data);
        if (data.name !== MessageName.APP_TO_SDK && data.name !== MessageName.APP_TO_APP || data.instanceId !== this.AMSSDK._instanceId) {
          return;
        }
        this._handleAppMessage(data);
      } else {
        console.warn(ERRORMESSAGE.NOT_JSON_FORMAT);
        this._dispatchToSDK({
          name: MessageName.APP_TO_SDK,
          instanceId: this.AMSSDK._instanceId,
          context: {
            event: 'onError',
            data: ERRORMESSAGE.NOT_JSON_FORMAT
          }
        });
      }
    }
    /**
     * @description Initialize subscription iframe message
     */
  }, {
    key: "_addEventListener",
    value: function _addEventListener() {
      this._removeEventListener();
      window.addEventListener('message', this._listener.bind(this));
    }
  }, {
    key: "_removeEventListener",
    value: function _removeEventListener() {
      window.removeEventListener('message', this._listener.bind(this));
    }
    /**
     * @description Processing messages from iframe
     */
  }, {
    key: "_handleAppMessage",
    value: function _handleAppMessage(data) {
      var eventKeyMap = [EVENT.error.name, EVENT.ready.name, EVENT.launch.name, EVENT.redirect.name, EVENT.sizeChanged.name, 'onPaymentMethodsSelected', EVENT.log.name];
      if (!eventKeyMap.includes(data.context.event)) {
        return;
      }
      if (data.context.event === 'onLaunch') {
        this._renderPaymentMethods(this.paymentMethodsResult);
      }
      if (data.context.event === 'onSizeChanged') {
        this.app.style.height = "".concat(data.context.data.height, "px");
        this.app.style.width = '100%';
        this.app.style.border = '0';
        this.app.style.overflow = 'hidden';
      }
      if (data.context.event === 'onPaymentMethodsSelected') data.context.event = 'onPaymentMethodSelected';
      // The plug-in communicates with the sdk after processing
      this._dispatchToSDK(data);
    }
    /**
     * @description Send message to SDK
     */
  }, {
    key: "_dispatchToSDK",
    value: function _dispatchToSDK(data) {
      var _data = Object.assign({
        name: MessageName.APP_TO_SDK,
        mode: this.AMSSDK.options.mode,
        appId: BASEPLUGINID,
        instanceId: this.AMSSDK._instanceId
      }, data);
      this.AMSSDK._eventCenter.emit("".concat(BASEPLUGINID, "-").concat(data.context.event), _data);
    }
    /**
     * @description Send message to iframe
     */
  }, {
    key: "_dispatchToApp",
    value: function _dispatchToApp(data) {
      if (this.app && this.app.contentWindow) {
        this.app.contentWindow.postMessage(JSON.stringify(data), this.appDomain);
      }
    }
    /**
     * @description Subscribe to messages from SDK
     */
  }, {
    key: "_subscribeFromSDK",
    value: function _subscribeFromSDK() {
      var eventKeyMap = {
        handleRequestPayment: this._handleRequestPayment
      };
      for (var key in eventKeyMap) {
        // eslint-disable-next-line no-prototype-builtins
        if (eventKeyMap.hasOwnProperty(key)) {
          this.AMSSDK._eventCenter.on("".concat(BASEPLUGINID, "-").concat(key), eventKeyMap[key].bind(this));
        }
      }
    }
    /**
     * @description Send rendering events to iframe
     */
  }, {
    key: "_renderPaymentMethods",
    value: function _renderPaymentMethods(paymentResult) {
      this._dispatchToApp({
        name: MessageName.SDK_TO_APP,
        mode: this.AMSSDK.options.mode,
        appId: BASEPLUGINID,
        instanceId: this.AMSSDK._instanceId,
        context: {
          event: 'renderPaymentMethods',
          data: paymentResult
        }
      });
    }
    /**
     * @description Send the post submission processing event, and the cashier applies the consumption result
     */
  }, {
    key: "_handleRequestPayment",
    value: function _handleRequestPayment(data) {
      this._dispatchToApp(data);
    }
  }]);
  return CheckoutApp;
}();
export { CheckoutApp as default };