'use client';
'use strict';

var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var jsxRuntime = require('react/jsx-runtime');
require('./css/index.css.js');
var auth = require('@web3auth/auth');
var noModal = require('@web3auth/no-modal');
var Bowser = require('bowser');
var client = require('react-dom/client');
var utils = require('../utils.js');
var Widget = require('./components/Widget/Widget.js');
var constants = require('./constants.js');
var AnalyticsContext = require('./context/AnalyticsContext.js');
var ThemeContext = require('./context/ThemeContext.js');
var interfaces = require('./interfaces.js');
var localeImport = require('./localeImport.js');
var utils$1 = require('./utils.js');

function createWrapperForModal(parentZIndex) {
  const existingWrapper = document.getElementById("w3a-parent-container");
  if (existingWrapper) existingWrapper.remove();
  const parent = document.createElement("section");
  parent.classList.add("w3a-parent-container");
  parent.setAttribute("id", "w3a-parent-container");
  parent.style.zIndex = parentZIndex;
  parent.style.position = "relative";
  document.body.appendChild(parent);
}
function createWrapperForEmbed(targetId) {
  const targetElement = document.getElementById(targetId);
  if (!targetElement) {
    noModal.log.error(`Element with ID ${targetId} not found`);
    return;
  }
  targetElement.innerHTML = `<div id="w3a-parent-container" class="w3a-parent-container"></div>`;
}
class LoginModal {
  constructor(_uiConfig, callbacks) {
    _defineProperty(this, "uiConfig", void 0);
    _defineProperty(this, "stateEmitter", void 0);
    _defineProperty(this, "chainNamespaces", void 0);
    _defineProperty(this, "walletRegistry", void 0);
    _defineProperty(this, "callbacks", void 0);
    _defineProperty(this, "externalWalletsConfig", void 0);
    _defineProperty(this, "analytics", void 0);
    _defineProperty(this, "initModal", async () => {
      const darkState = {
        isDark: this.isDark
      };
      const useLang = this.uiConfig.defaultLanguage || auth.LANGUAGES.en;
      // Load new language resource
      if (useLang === auth.LANGUAGES.de) {
        Promise.resolve().then(function () { return require('./i18n/german.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.ja) {
        Promise.resolve().then(function () { return require('./i18n/japanese.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.ko) {
        Promise.resolve().then(function () { return require('./i18n/korean.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.zh) {
        Promise.resolve().then(function () { return require('./i18n/mandarin.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.es) {
        Promise.resolve().then(function () { return require('./i18n/spanish.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.fr) {
        Promise.resolve().then(function () { return require('./i18n/french.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.pt) {
        Promise.resolve().then(function () { return require('./i18n/portuguese.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.nl) {
        Promise.resolve().then(function () { return require('./i18n/dutch.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.tr) {
        Promise.resolve().then(function () { return require('./i18n/turkish.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      } else if (useLang === auth.LANGUAGES.en) {
        Promise.resolve().then(function () { return require('./i18n/english.json.js'); }).then(messages => {
          localeImport.addResourceBundle(useLang, "translation", messages.default);
          return localeImport.changeLanguage(useLang);
        }).catch(error => {
          noModal.log.error(error);
        });
      }
      return new Promise(resolve => {
        var _this$uiConfig, _this$uiConfig$theme, _this$uiConfig2;
        this.stateEmitter.once("MOUNTED", () => {
          noModal.log.info("rendered");
          this.setState({
            status: interfaces.MODAL_STATUS.INITIALIZED,
            web3authClientId: this.uiConfig.web3authClientId,
            web3authNetwork: this.uiConfig.web3authNetwork,
            authBuildEnv: this.uiConfig.authBuildEnv
          });
          return resolve();
        });
        if (this.uiConfig.widgetType === noModal.WIDGET_TYPE.MODAL) {
          createWrapperForModal(this.uiConfig.modalZIndex);
        } else if (this.uiConfig.widgetType === noModal.WIDGET_TYPE.EMBED) {
          createWrapperForEmbed(this.uiConfig.targetId);
        } else {
          throw noModal.WalletInitializationError.invalidParams(`Invalid widget type: ${this.uiConfig.widgetType}`);
        }
        const container = document.getElementById("w3a-parent-container");
        if (darkState.isDark) {
          container.classList.add("w3a--dark");
        } else {
          container.classList.remove("w3a--dark");
        }
        const root = client.createRoot(container);
        root.render(jsxRuntime.jsx(ThemeContext.ThemedContext.Provider, {
          value: darkState,
          children: jsxRuntime.jsx(AnalyticsContext.AnalyticsContext.Provider, {
            value: {
              analytics: this.analytics
            },
            children: jsxRuntime.jsx(Widget, {
              stateListener: this.stateEmitter,
              appLogo: darkState.isDark ? this.uiConfig.logoDark : this.uiConfig.logoLight,
              appName: this.uiConfig.appName,
              chainNamespaces: this.chainNamespaces,
              walletRegistry: this.walletRegistry,
              deviceDetails: this.deviceDetails,
              handleShowExternalWallets: this.handleShowExternalWallets,
              handleExternalWalletClick: this.handleExternalWalletClick,
              handleSocialLoginClick: this.handleSocialLoginClick,
              closeModal: this.closeModal,
              uiConfig: this.uiConfig
            })
          })
        }));
        const isDefaultColors = ((_this$uiConfig = this.uiConfig) === null || _this$uiConfig === void 0 || (_this$uiConfig = _this$uiConfig.theme) === null || _this$uiConfig === void 0 ? void 0 : _this$uiConfig.primary) === constants.DEFAULT_PRIMARY_COLOR && ((_this$uiConfig$theme = this.uiConfig.theme) === null || _this$uiConfig$theme === void 0 ? void 0 : _this$uiConfig$theme.onPrimary) === constants.DEFAULT_ON_PRIMARY_COLOR;
        if ((_this$uiConfig2 = this.uiConfig) !== null && _this$uiConfig2 !== void 0 && _this$uiConfig2.theme && !isDefaultColors) {
          import('color').then(({
            default: Color
          }) => {
            const rootElement = document.getElementById("w3a-parent-container");
            auth.applyWhiteLabelTheme(Color, rootElement, this.uiConfig.theme);
            return;
          }).catch(error => {
            noModal.log.error(error);
          });
        }
      });
    });
    _defineProperty(this, "addSocialLogins", (connector, loginMethods, loginMethodsOrder, uiConfig) => {
      this.setState({
        socialLoginsConfig: {
          connector,
          loginMethods,
          loginMethodsOrder,
          uiConfig
        }
      });
      noModal.log.info("addSocialLogins", connector, loginMethods, loginMethodsOrder, uiConfig);
    });
    _defineProperty(this, "addWalletLogins", (externalWalletsConfig, options) => {
      this.externalWalletsConfig = externalWalletsConfig;
      const isMMAvailable = !!externalWalletsConfig[noModal.WALLET_CONNECTORS.METAMASK];
      this.setState({
        externalWalletsConfig,
        externalWalletsInitialized: !!options.externalWalletsInitialized,
        showExternalWalletsOnly: !!options.showExternalWalletsOnly,
        externalWalletsVisibility: isMMAvailable ? false : !!options.externalWalletsVisibility
      });
    });
    _defineProperty(this, "open", () => {
      var _this$analytics, _this$walletRegistry, _this$walletRegistry2;
      this.setState({
        modalVisibility: true
      });
      (_this$analytics = this.analytics) === null || _this$analytics === void 0 || _this$analytics.track(noModal.ANALYTICS_EVENTS.LOGIN_MODAL_OPENED, _objectSpread(_objectSpread({
        chain_namespaces: this.chainNamespaces,
        wallet_registry_count: Object.keys((_this$walletRegistry = this.walletRegistry) === null || _this$walletRegistry === void 0 ? void 0 : _this$walletRegistry.default).length + Object.keys((_this$walletRegistry2 = this.walletRegistry) === null || _this$walletRegistry2 === void 0 ? void 0 : _this$walletRegistry2.others).length,
        external_wallet_connectors: Object.keys(this.externalWalletsConfig || {})
      }, noModal.getWhitelabelAnalyticsProperties(this.uiConfig)), utils.getLoginModalAnalyticsProperties(this.uiConfig)));
      if (this.callbacks.onModalVisibility) {
        this.callbacks.onModalVisibility(true);
      }
    });
    _defineProperty(this, "closeModal", () => {
      var _this$analytics2;
      this.setState({
        modalVisibility: false,
        externalWalletsVisibility: false
      });
      (_this$analytics2 = this.analytics) === null || _this$analytics2 === void 0 || _this$analytics2.track(noModal.ANALYTICS_EVENTS.LOGIN_MODAL_CLOSED);
      if (this.callbacks.onModalVisibility) {
        this.callbacks.onModalVisibility(false);
      }
    });
    _defineProperty(this, "initExternalWalletContainer", () => {
      this.setState({
        hasExternalWallets: true
      });
    });
    _defineProperty(this, "handleShowExternalWallets", status => {
      if (this.callbacks.onInitExternalWallets) {
        this.callbacks.onInitExternalWallets({
          externalWalletsInitialized: status
        });
      }
    });
    _defineProperty(this, "handleExternalWalletClick", params => {
      noModal.log.info("external wallet clicked", params);
      const {
        connector,
        chainNamespace
      } = params;
      if (this.callbacks.onExternalWalletLogin) {
        this.callbacks.onExternalWalletLogin({
          connector,
          loginParams: {
            chainNamespace
          }
        });
      }
    });
    _defineProperty(this, "handleSocialLoginClick", params => {
      var _this$analytics3;
      noModal.log.info("social login clicked", params);
      const {
        connector,
        loginParams
      } = params;
      (_this$analytics3 = this.analytics) === null || _this$analytics3 === void 0 || _this$analytics3.track(noModal.ANALYTICS_EVENTS.SOCIAL_LOGIN_SELECTED, {
        connector,
        auth_connection: loginParams.authConnection,
        auth_connection_id: loginParams.authConnectionId,
        group_auth_connection_id: loginParams.groupedAuthConnectionId
      });
      if (this.callbacks.onSocialLogin) {
        this.callbacks.onSocialLogin({
          connector,
          loginParams
        });
      }
    });
    _defineProperty(this, "setState", newState => {
      this.stateEmitter.emit("STATE_UPDATED", newState);
    });
    _defineProperty(this, "handleConnectorData", connectorData => {
      if (connectorData.connectorName === noModal.WALLET_CONNECTORS.WALLET_CONNECT_V2) {
        const walletConnectData = connectorData.data;
        if (walletConnectData.uri) {
          this.setState({
            walletConnectUri: walletConnectData.uri
          });
        }
      }
      if (connectorData.connectorName === noModal.WALLET_CONNECTORS.METAMASK) {
        const metamaskData = connectorData.data;
        if (metamaskData.uri) {
          this.setState({
            metamaskConnectUri: metamaskData.uri
          });
        }
      }
    });
    _defineProperty(this, "subscribeCoreEvents", listener => {
      listener.on(noModal.CONNECTOR_EVENTS.CONNECTING, data => {
        var _this$externalWallets;
        noModal.log.info("connecting with connector", data);
        // don't show loader in case of wallet connect, because currently it listens for incoming connections without any user interaction
        if ((data === null || data === void 0 ? void 0 : data.connector) === noModal.WALLET_CONNECTORS.WALLET_CONNECT_V2) return;
        // don't show loader in case of metamask qr code, because currently it listens for incoming connections without any user interaction
        const isMetamaskInjected = (_this$externalWallets = this.externalWalletsConfig) === null || _this$externalWallets === void 0 || (_this$externalWallets = _this$externalWallets[noModal.WALLET_CONNECTORS.METAMASK]) === null || _this$externalWallets === void 0 ? void 0 : _this$externalWallets.isInjected;
        if ((data === null || data === void 0 ? void 0 : data.connector) === noModal.WALLET_CONNECTORS.METAMASK && !isMetamaskInjected && this.deviceDetails.platform === "desktop") return;
        this.setState({
          status: interfaces.MODAL_STATUS.CONNECTING
        });
      });
      listener.on(noModal.CONNECTOR_EVENTS.CONNECTED, data => {
        noModal.log.debug("connected with connector", data);
        // only show success if not being reconnected again.
        if (!data.reconnected && data.loginMode === noModal.LOGIN_MODE.MODAL) {
          this.setState({
            status: interfaces.MODAL_STATUS.CONNECTED,
            modalVisibility: true,
            postLoadingMessage: "modal.post-loading.connected",
            currentPage: constants.PAGES.LOGIN
          });
        } else {
          this.setState({
            status: interfaces.MODAL_STATUS.CONNECTED
          });
        }
      });
      // TODO: send connector name in error
      listener.on(noModal.CONNECTOR_EVENTS.ERRORED, (error, loginMode) => {
        noModal.log.error("error", error, error.message);
        if (loginMode === noModal.LOGIN_MODE.NO_MODAL) return;
        if (error.code === 5000) {
          if (this.uiConfig.displayErrorsOnModal) this.setState({
            modalVisibility: true,
            postLoadingMessage: error.message || "modal.post-loading.something-wrong",
            status: interfaces.MODAL_STATUS.ERRORED
          });else this.setState({
            modalVisibility: false
          });
        } else {
          this.setState({
            modalVisibility: true,
            status: interfaces.MODAL_STATUS.INITIALIZED
          });
        }
      });
      listener.on(noModal.CONNECTOR_EVENTS.DISCONNECTED, () => {
        this.setState({
          status: interfaces.MODAL_STATUS.INITIALIZED,
          externalWalletsVisibility: false
        });
        // this.toggleMessage("");
      });
      listener.on(noModal.CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, connectorData => {
        this.handleConnectorData(connectorData);
      });
    });
    this.uiConfig = _uiConfig;
    if (!_uiConfig.logoDark) this.uiConfig.logoDark = constants.DEFAULT_LOGO_DARK;
    if (!_uiConfig.logoLight) this.uiConfig.logoLight = constants.DEFAULT_LOGO_LIGHT;
    if (!_uiConfig.mode) this.uiConfig.mode = "light";
    if (!_uiConfig.modalZIndex) this.uiConfig.modalZIndex = "99998";
    if (typeof _uiConfig.displayErrorsOnModal === "undefined") this.uiConfig.displayErrorsOnModal = true;
    if (!_uiConfig.appName) this.uiConfig.appName = "Web3Auth";
    if (!_uiConfig.loginGridCol) this.uiConfig.loginGridCol = 3;
    if (!_uiConfig.primaryButton) this.uiConfig.primaryButton = "socialLogin";
    if (!_uiConfig.defaultLanguage) this.uiConfig.defaultLanguage = utils$1.getUserLanguage(_uiConfig.defaultLanguage);
    if (!_uiConfig.widgetType) this.uiConfig.widgetType = noModal.WIDGET_TYPE.MODAL;
    if (_uiConfig.widgetType === noModal.WIDGET_TYPE.EMBED && !_uiConfig.targetId) {
      noModal.log.error("targetId is required for embed widget");
      throw noModal.WalletInitializationError.invalidParams("targetId is required for embed widget");
    }
    this.stateEmitter = new auth.SafeEventEmitter();
    this.chainNamespaces = _uiConfig.chainNamespaces;
    this.walletRegistry = _uiConfig.walletRegistry;
    this.callbacks = callbacks;
    this.analytics = _uiConfig.analytics;
    this.subscribeCoreEvents(this.uiConfig.connectorListener);
  }
  get isDark() {
    return this.uiConfig.mode === "dark" || this.uiConfig.mode === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches;
  }
  get deviceDetails() {
    if (typeof window === "undefined") return {
      platform: "mobile",
      browser: "chrome",
      os: "ios"
    };
    const browserData = Bowser.getParser(window.navigator.userAgent);
    return {
      platform: browserData.getPlatformType(),
      browser: browserData.getBrowserName().toLowerCase(),
      os: browserData.getOSName()
    };
  }
}

exports.LoginModal = LoginModal;
