import { jsx as m, jsxs as K, Fragment as Vo } from "react/jsx-runtime";
import S from "prop-types";
import jo from "lodash/omit";
import Ko from "lodash/pick";
import Te from "lodash/cloneDeep";
import Z from "lodash/isFunction";
import u from "lodash/isUndefined";
import $o from "lodash/defaultsDeep";
import qo from "js-cookie";
import Xo from "eventemitter3";
import Qo from "p-wait-for";
import { useTheme as Yo, Typography as Jo, Box as $, CircularProgress as Zo } from "@mui/material";
import { getVisitorId as q, mergeIgnoreEmpty as et, isUrl as ot, ensureVisitorId as tt, setVisitorId as ke } from "@arcblock/ux/lib/Util";
import ae, { ToastProvider as ye } from "@arcblock/ux/lib/Toast";
import it from "@arcblock/ux/lib/Center";
import { useReactive as Ie, useCreation as Le, useMemoizedFn as f, usePrevious as rt, useLatest as De, useUpdateEffect as le, useMount as nt } from "ahooks";
import { joinURL as H } from "ufo";
import { Icon as st } from "@iconify/react";
import ct from "@iconify-icons/material-symbols/keyboard-double-arrow-right-rounded";
import at from "@arcblock/react-hooks/lib/useBrowser";
import lt from "@arcblock/ux/lib/Dialog/use-confirm";
import _e from "@arcblock/ux/lib/DID";
import Ee from "@arcblock/ux/lib/Avatar";
import { getCurrentAppPid as dt } from "@arcblock/ux/lib/SessionUser/libs/utils";
import { translate as pt } from "@arcblock/ux/lib/Locale/util";
import { getBlockletSDK as ft } from "@blocklet/js-sdk";
import b from "@arcblock/bridge";
import { getFederatedEnabled as ut } from "@arcblock/ux/lib/Util/federated";
import wt from "lodash/noop";
import ht from "lodash/isNil";
import { ReactGA as mt } from "@arcblock/ux/lib/withTracker";
import { useState as gt, useEffect as St } from "react";
import de from "../Storage/index.js";
import { formatCacheTtl as Pt, getBrowserLang as At, debug as h, decodeUrlParams as ve, sleep as E, debugTmp as xe, updateConnectedInfo as ee, getAppId as oe, logger as Oe } from "../utils.js";
import Re from "./window-focus-aware.js";
import { OAuthContext as bt, OAuthConsumer as Ct, OAuthProvider as Ne, useOAuth as Tt } from "../OAuth/context.js";
import { PasskeyContext as kt, PasskeyConsumer as yt, PasskeyProvider as We, usePasskey as It } from "../Passkey/context.js";
import "../Passkey/actions.js";
import Lt, { getWalletDid as Dt } from "../User/use-did.js";
import _t from "../User/wrap-did.js";
import Et from "./hooks/use-federated.js";
import vt from "./hooks/use-session-token.js";
import xt from "./hooks/use-protected-routes.js";
import { SessionContext as qe } from "./context.js";
import Ot from "../Connect/use-connect.js";
import { EVENTS as a } from "./libs/constants.js";
import { translations as B } from "./libs/locales.js";
import { NotOpenError as Rt } from "../error.js";
import { SESSION_TOKEN_STORAGE_KEY as Xe, REFRESH_TOKEN_STORAGE_KEY as Qe, CSRF_TOKEN_STORAGE_KEY as Nt, API_DID_PREFIX as Wt, DEFAULT_TIMEOUT as Ft, BLOCKLET_SERVICE_PATH_PREFIX as G, DID_SPACES_BASE_URL as Bt } from "../constant.js";
import { getMobileVisitorId as Ut, checkEnableAutoLogin as Mt, login as Ht } from "./libs/login-mobile.js";
import Gt from "../Connect/hooks/use-quick-connect.js";
import { didSpacesIsRequired as Fe } from "./libs/did-spaces.js";
import zt from "./did-spaces-guide.js";
import { FederatedProvider as Vt, useFederatedContext as jt } from "../Federated/context.js";
import Kt from "./hooks/use-verify.js";
import { gaLoginSuccessHandler as Be, gaLoginFailedHandler as Ue, gaSwitchPassportSuccessHandler as Me, gaSwitchPassportFailedHandler as He, gaBindWalletSuccessHandler as Ge, gaBindWalletFailedHandler as ze } from "./handler.js";
import { loginFederatedMaster as Zi, mountFederatedIframe as er } from "./libs/federated.js";
const { Provider: $t, Consumer: Ve } = qe, je = {
  en: "DID Connect timeout, please reopen DID Connect popup",
  zh: "DID Connect 超时, 请重新打开 DID Connect"
}, Ke = {
  en: "DID Connect is already opened, please wait for it to complete",
  zh: "DID Connect 已打开，请等待完成"
};
function $e(X = Xe, Q = "ls", te = {}, k = {}) {
  let D = "/";
  globalThis?.blocklet?.prefix && (D = globalThis.blocklet.prefix), typeof k == "boolean" && (k = {
    appendAuthServicePrefix: k,
    extraParams: {}
  }), $o(k, {
    rolling: !0,
    appendAuthServicePrefix: !1,
    extraParams: {},
    refreshTokenStorageKey: Qe
  });
  function O(L) {
    if (globalThis.blocklet)
      if (L?.user) {
        const v = {
          did: L.user.did,
          host: window.location.host,
          appPid: globalThis.blocklet.appPid,
          visitorId: q(),
          sourceAppPid: L.user.sourceAppPid,
          fullName: L.user.fullName
        };
        h("bridge callArc: onLogin", v), b.callArc("onLogin", { ...v, user: v });
      } else
        b.callArc("onLogin", { error: "no user", code: 400 }), h("notifyBridge failed", { sessionState: L });
  }
  const Y = de(X, Q, te), z = de(Nt, "cookie", {
    secure: !0,
    sameSite: "strict"
  }), Ye = de(k.refreshTokenStorageKey, "ls");
  function pe({ ...L }) {
    const v = ft(), n = Object.assign({}, L);
    u(n.serviceHost) && (n.serviceHost = D), u(n.locale) && (n.locale = ""), u(n.action) && (n.action = "login"), u(n.prefix) && (n.prefix = Wt), u(n.appendAuthServicePrefix) && (n.appendAuthServicePrefix = !1), u(n.extraParams) && (n.extraParams = {}), u(n.options) && (n.options = {}), u(n.autoConnect) && (n.autoConnect = !1), u(n.autoDisconnect) && (n.autoDisconnect = !0), u(n.useSocket) && (n.useSocket = !0), u(n.timeout) && (n.timeout = Ft * 1e3), u(n.webWalletUrl) && (n.webWalletUrl = void 0), u(n.protectedRoutes) && (n.protectedRoutes = ["*"]), u(n.apiOptions) && (n.apiOptions = {}), u(n.lazyRefreshToken) && (n.lazyRefreshToken = !1);
    const { connectApi: y, connectHolder: Ze } = Ot(), [eo, fe] = gt(0), I = at(), { requestStorageAccess: oo } = jt(), { palette: to } = Yo(), U = new URLSearchParams(window.location.search), c = Ie({
      extraParams: {},
      options: {},
      currentLocale: n.locale,
      allowWallet: void 0,
      openMode: "window",
      get autoConnect() {
        return typeof n.autoConnect == "boolean" ? n.autoConnect : !!n.autoLogin;
      },
      get prefix() {
        return k.appendAuthServicePrefix || n.appendAuthServicePrefix ? H(G, n.prefix) : n.prefix;
      },
      get notificationPrefix() {
        const e = "/api/notifications";
        return k.appendAuthServicePrefix || n.appendAuthServicePrefix ? H(G, e) : e;
      }
    }), i = Ie({
      action: n.action,
      error: "",
      initialized: !1,
      loading: !1,
      open: !1,
      user: null,
      provider: "",
      walletOS: "",
      baseUrl: "",
      unReadCount: 0
      // 不可以直接个性 props.autoConnect (readonly)
    }), P = Le(() => n.locale || c.currentLocale || At(), [n.locale, c.currentLocale]), { confirmApi: io, confirmHolder: ro } = lt(), R = f(() => {
      if (i.open && !I.arcSphere) {
        const e = Ke[P] || Ke.en;
        throw ae.warning(e), new Error(e);
      }
    }), d = Le(() => new Xo(), []);
    St(() => (d.on(a.LOGIN, Be), d.on(a.LOGIN_FAILED, Ue), d.on(a.SWITCH_PASSPORT, Me), d.on(a.SWITCH_PASSPORT_FAILED, He), d.on(a.BIND_WALLET, Ge), d.on(a.BIND_WALLET_FAILED, ze), () => {
      d.off(a.LOGIN, Be), d.off(a.LOGIN_FAILED, Ue), d.off(a.SWITCH_PASSPORT, Me), d.off(a.SWITCH_PASSPORT_FAILED, He), d.off(a.BIND_WALLET, Ge), d.off(a.BIND_WALLET_FAILED, ze);
    }), [d]);
    const M = f((e, o, t) => {
      const s = {
        login: [a.LOGIN, a.CANCEL_LOGIN],
        "bind-wallet": [a.BIND_WALLET, a.CANCEL_BIND_WALLET],
        "switch-passport": [a.SWITCH_PASSPORT, a.CANCEL_SWITCH_PASSPORT],
        "switch-profile": [a.SWITCH_PROFILE, a.CANCEL_SWITCH_PROFILE],
        // HACK: 对于内部来说，switch-did 就是 login，所以内部的监听事件仍然是 login
        "switch-did": [a.LOGIN, a.CANCEL_LOGIN],
        // @FIXME: @zhanghan 整个事件发射的机制需要重构，目前的实现不是很优雅，对于用户来说不是很好用。 https://github.com/ArcBlock/ux/pull/1414#discussion_r1904830954
        "did-space-connected": [a.DID_SPACE_CONNECTED]
      };
      if (!Object.keys(s).includes(e))
        return;
      const l = async (...p) => {
        Z(o) && await o(...p), d.emit(e, ...p);
      };
      d.once(s[e][0], l), d.once(s[e][1], async (...p) => {
        Z(l) && d.off(s[e][0], l), Z(t) && await t(...p), d.emit(`cancel-${e}`, ...p);
      });
    }), no = rt(i.initialized, (e, o) => e !== o || e === !0 && o === !0), {
      syncSessionSate: so,
      handleRefreshUser: C,
      handleRefreshToken: co,
      renewToken: ao,
      clearSession: ue,
      handleLoginResult: x,
      decrypt: _,
      service: lo,
      getSessionToken: po,
      getRefreshToken: fo,
      setRefreshToken: uo,
      setSessionToken: wo
    } = vt({
      state: i,
      pageState: c,
      sessionTokenStorage: Y,
      refreshTokenStorage: Ye,
      csrfTokenStorage: z,
      serviceHost: n.serviceHost,
      apiOptions: n.apiOptions,
      lazyRefreshToken: n.lazyRefreshToken,
      onRefresh({ type: e, sessionToken: o, refreshToken: t, user: s }) {
        if (h("onRefresh", { type: e, user: s }), globalThis.blocklet) {
          const l = {
            did: s.did,
            host: window.location.host,
            appPid: globalThis.blocklet.appPid,
            visitorId: q(),
            sourceAppPid: s.sourceAppPid,
            fullName: s.fullName
          };
          e === "refreshToken" ? (h("bridge callArc: onRefreshToken"), b.callArc("onRefreshToken", {
            sessionToken: o,
            refreshToken: t,
            user: l
          })) : e === "refreshUser" && (h("bridge callArc: onRefreshUser"), b.callArc("onRefreshUser", {
            sessionToken: o,
            refreshToken: t,
            user: l
          }));
        }
      }
    }), ho = Kt({ state: i, connectApi: y }), we = f((e, o = {}, t = {}) => {
      R();
      const s = e;
      typeof s == "object" && (e = s.onSuccess, o = s.extraParams || {}, t = s.options || {}, t.origin = s.origin || ""), (!i.user || t.origin === "switch-did") && (t.origin === "switch-did" ? M("switch-did", e, s?.onCancel) : M("login", e, s?.onCancel), c.extraParams = o, c.options = t, i.action = "login", F());
    }), mo = f((e, o = {}) => {
      const t = e;
      return function(...l) {
        const p = this;
        return (async () => {
          try {
            const g = await ho(o);
            if (!g.sessionId)
              throw new Error("Authentication failed");
            return await t.call(p, g, ...l);
          } catch (g) {
            throw console.error("Authentication failed", g), g;
          }
        })();
      };
    }), ie = f(async (e, o = {}, t = {}) => {
      R();
      const s = e;
      typeof s == "object" && (e = s.onSuccess, o = s.extraParams || {}, t = s.options || {}), u(o?.inviter) && window.localStorage.getItem("inviter") && (o.inviter = window.localStorage.getItem("inviter"));
      const { params: l } = await ve();
      if (u(o?.forceConnected) && l?.forceConnected && (o.forceConnected = l.forceConnected, u(t.showQuickConnect) && (t.showQuickConnect = !1)), u(o?.sourceAppPid) && !u(l?.sourceAppPid) && (o.sourceAppPid = l.sourceAppPid), o?.openMode === "redirect") {
        const w = o?.redirect || "/", T = new URL(`${G}/login`, window.location.origin);
        T.searchParams.set("redirect", w), o?.forceConnected && T.searchParams.set("forceConnected", o?.forceConnected), u(o?.sourceAppPid) || T.searchParams.set("sourceAppPid", o?.sourceAppPid), u(o?.inviter) || T.searchParams.set("inviter", o?.inviter), t?.origin && T.searchParams.set("origin", t.origin), window.location.href = T.href;
        return;
      }
      let p = o?.sourceAppPid;
      u(p) && No && (p = Wo.appPid), await Qo(() => i.initialized), typeof t == "string" && (t = { origin: t });
      const g = Te(o);
      g.passkeyBehavior = "both", c.allowWallet = void 0;
      const r = g?.openMode || n?.extraParams?.openMode;
      u(r) ? p ? p !== globalThis.blocklet.appPid && ut(globalThis.blocklet) && (c.openMode = "window") : c.openMode = "popup" : c.openMode = r, c.openMode === "window" && !I.arcSphere && !I.wallet && await oo() && (c.openMode = "popup"), p ? i.baseUrl = globalThis.blocklet.appUrl : i.baseUrl = "", we(e, g, t);
    }), he = f(async (e) => {
      const o = q();
      if (globalThis.blocklet && (v.user.logout({ visitorId: o }).catch((t) => {
        console.warn("Failed to logout remote", t);
      }), await E(100)), globalThis.blocklet) {
        const t = {
          visitorId: o,
          appPid: globalThis.blocklet.appPid,
          userDid: i.user.did
        };
        h("bridge callArc: onLogout", t), b.callArc("onLogout", t);
      }
      xe("[clearSession] createSessionContext -> logout:"), ue(), j(), i.user = null, i.provider = "", i.walletOS = "", i.error = "", i.loading = !1, d.emit("logout"), mt.set({
        user_id: void 0
      }), typeof e == "function" && e();
    }), {
      userSessions: go,
      refresh: So,
      loaded: Po,
      loginUserSession: re
    } = Gt({
      appPid: dt(i.user),
      loginAppPid: globalThis?.blocklet?.appPid,
      sourceAppPid: i?.user?.sourceAppPid,
      autoFetch: !1,
      fetchAll: !0
    }), Ao = f((e, o) => {
      if (!globalThis.blocklet) return null;
      const t = globalThis.blocklet?.settings?.actionConfig?.[e];
      return t ? t[o] || t.en : null;
    }), N = f(async () => {
      i?.user || await new Promise((e) => {
        ie(() => {
          e();
        });
      });
    }), ne = f((e, o = {}, t = {}) => {
      R();
      const s = e;
      typeof s == "object" && (e = s.onSuccess, o = s.extraParams || {}, t = s.options || {}), typeof t == "string" && (t = { origin: t }), t?.userSession ? re(t.userSession).then((l) => {
        ee(
          {
            connected_did: t.userSession.user.did,
            connected_pk: t.userSession.user.pk,
            connected_wallet_os: t.userSession.extra.walletOS,
            connected_app: oe()
          },
          !0
        ), M("switch-did", e), x({ ...l, encrypted: !1 }), C({ showProgress: !0 }).then(async () => {
          await E(200), d.emit(a.LOGIN, l, _, A.current), O(A.current), await W();
        }).catch((p) => {
          throw d.emit(a.LOGIN_FAILED, p), p;
        });
      }) : (u(o?.forceConnected) && (o.forceConnected = !1), o.passkeyBehavior = "both", ie(e, o, { ...t, origin: "switch-did" }));
    }), bo = f(async () => {
      await v.user.refreshProfile();
    }), Co = f(async (e, o = {}) => {
      await N(), R();
      const t = e;
      typeof t == "object" && (e = t.onSuccess, o = t.extraParams || {}), M("switch-profile", e, t?.onCancel), c.extraParams = o, c.options = {}, i.action = "switch-profile", F();
    }), To = f(async (e, o = {}) => {
      await N(), R();
      const t = e;
      typeof t == "object" && (e = t.onSuccess, o = t.extraParams || {}), M("switch-passport", e, t?.onCancel), c.extraParams = o, c.options = {}, i.action = "switch-passport", F();
    }), ko = f(async ({ extraParams: e = {}, onSuccess: o = () => {
    }, ...t } = {}) => {
      await N(), R(), c.extraParams = {
        referrer: window.location.href,
        purpose: "authorize-for-import",
        ...e,
        saveConnect: !1
        // 连接 spaces 不保存连接信息
      }, c.options = {}, i.action = "connect-to-did-spaces-for-user", F({
        hideCloseButton: !0,
        onSuccess: o,
        ...t
      });
    }), me = f(async ({ extraParams: e = {}, onSuccess: o = {} } = {}) => {
      await N(), ko({
        extraParams: {
          // service 交互
          purpose: "authorize-for-import",
          ...e
        },
        onSuccess: o,
        hideCloseButton: !1
      });
    }), { didSpacesGuideApi: J, DidSpacesGuideView: yo } = zt({
      autoClose: !1
    }), W = async ({ extraParams: e = {}, onSuccess: o = () => {
    } } = {}) => {
      await N(), await Fe(i?.user) && (J.open(), J.onConnect((t = wt) => {
        const s = {
          prefix: "/connect-to-did-space",
          custom: !0,
          extraParams: {
            provider: "wallet",
            appPid: window.blocklet?.appPid,
            appDid: window.blocklet?.appId,
            appName: window.blocklet?.appName,
            appDescription: window.blocklet?.appDescription,
            appUrl: window.blocklet?.appUrl,
            referrer: window.location.href,
            connectScope: "user",
            ...e
          },
          onSuccess: async (l, p) => {
            const g = p ? p(l.spaceGateway) : l.spaceGateway;
            await v.user.updateDidSpace({ spaceGateway: g }), await C({ showProgress: !0 }), await o(l, p), await J.close(), d.emit(a.DID_SPACE_CONNECTED, l, p), globalThis.blocklet && (h("bridge callArc: onDidSpaceConnected"), b.callArc("onDidSpaceConnected")), t(!0);
          },
          onError: (l) => {
            console.error(l), ae.error(l.message), J.close(), t(!1);
          },
          onClose: () => {
            t();
          }
        };
        y.openPopup(s, {
          baseUrl: Bt
        });
      }));
    }, ge = f(async (e, o = {}) => {
      if (await N(), Dt(i.user)) {
        e({}, _, A.current);
        return;
      }
      R();
      const t = e;
      typeof t == "object" && (e = t.onSuccess), M("bind-wallet", e, t?.onCancel), c.extraParams = o, c.options = {}, i.action = "bind-wallet", F();
    }), se = f(async (e) => {
      h("onSwitchPassport", { result: e }), c.extraParams = {}, c.options = {}, x(e), i.loading = !1, await C({ showProgress: !0 }), await E(200), d.emit(a.SWITCH_PASSPORT, e, _, A.current), globalThis.blocklet && (h("bridge callArc: onSwitchPassport"), b.callArc("onSwitchPassport"));
    }), Io = f((e) => {
      d.emit(a.SWITCH_PASSPORT_FAILED, e);
    }), V = f(async (e) => {
      if (i.action === "switch-passport") {
        se(e);
        return;
      }
      h("onLogin", { result: e }), c.extraParams = {}, c.options = {}, x(e), i.loading = !1, await C({ showProgress: !0 }), await E(200), i.action === "login" && (h("onLogin: emit LOGIN event", { result: e }), d.emit(a.LOGIN, e, _, A.current), O(A.current), W());
    }), Lo = f((e) => {
      d.emit(a.LOGIN_FAILED, e);
    }), Do = f((e) => {
      c.extraParams = {}, c.options = {}, x(e), i.loading = !1, C({ showProgress: !0 }).then(async () => {
        await E(100), d.emit(a.BIND_WALLET, e, _, A.current), globalThis.blocklet && (h("bridge callArc: onBindWallet"), b.callArc("onBindWallet"));
      });
    }), _o = f((e) => {
      d.emit(a.BIND_WALLET_FAILED, e, A);
    }), Eo = f((e) => {
      h("onSwitchProfile", { result: e }), c.extraParams = {}, c.options = {}, i.loading = !1, C({ showProgress: !0 }).then(async () => {
        await E(100), d.emit(a.SWITCH_PROFILE, e, _, A.current), globalThis.blocklet && (h("bridge callArc: onSwitchProfile"), b.callArc("onSwitchProfile"));
      });
    }), vo = f((e) => {
      c.extraParams = {}, c.options = {}, j();
      const o = {
        login: a.CANCEL_LOGIN,
        "switch-profile": a.CANCEL_SWITCH_PROFILE,
        "switch-passport": a.CANCEL_SWITCH_PASSPORT,
        "bind-wallet": a.CANCEL_BIND_WALLET
      }, t = {
        login: "offLogin",
        "switch-profile": "offSwitchProfile",
        "switch-passport": "offSwitchPassport",
        "bind-wallet": "offBindWallet"
      };
      d.emit(o[e]), globalThis.blocklet && (h(`bridge callArc: ${t[e]}`), b.callArc(`${t[e]}`));
    }), xo = f((e, ...o) => {
      try {
        ce[e](...o);
      } catch (t) {
        Oe.error("Catch error in onSuccess", {
          action: e,
          args: o,
          err: t
        }), ce[`${e}-failed`]?.(t, ...o);
      }
    }), Oo = f((e, o, ...t) => {
      ce[`${e}-failed`]?.(o, ...t);
    }), {
      federatedMaster: Ro,
      federatedEnabled: No,
      master: Wo
    } = Et({
      locale: P,
      decrypt: _,
      login: we,
      handleLoginResult: x,
      handleRefreshUser: C,
      setRefreshToken: uo,
      setSessionToken: wo
    }), { checkMatch: Fo } = xt({ protectedRoutes: n.protectedRoutes || [] }), Bo = De(go), Se = f(async () => (Po || (await So(), await E(100)), Bo.current)), j = f(() => {
      i.open = !1, y.close();
    }), F = async (e = {}) => {
      let o = i.action;
      c?.options?.origin === "switch-did" && (o = c?.options?.origin);
      const t = B[o], s = Ao(o, P), l = et(t[P] || t.en, s || {}), p = {
        ...k.extraParams,
        ...n.extraParams,
        ...c.extraParams,
        previousUserDid: i?.user?.did,
        email: i?.user?.email
      };
      if (o === "switch-did" && p?.forceConnected) {
        const r = (w, T = {}) => pt(B["switch-specified-did"], w, P, "en", T);
        l.title = r("title"), l.scan = r("scan", { did: p.forceConnected }), l.confirm = r("confirm"), l.success = r("success");
      }
      delete p?.openMode;
      const g = {
        action: i.action,
        locale: P,
        hideCloseButton: e?.hideCloseButton,
        extraParams: p,
        options: { ...n.options || {}, ...c.options },
        checkTimeout: n.timeout,
        webWalletUrl: n.webWalletUrl,
        messages: l,
        useSocket: n.useSocket,
        ...jo(n, [
          "action",
          "locale",
          // NOTICE: 将 serviceHost 也透传给 DID Connect 组件
          // 'serviceHost',
          "appendAuthServicePrefix",
          "autoDisconnect",
          "children",
          "timeout",
          "extraParams",
          "options",
          "webWalletUrl",
          "messages",
          "useSocket",
          "lazyRefreshToken",
          "apiOptions",
          "protectedRoutes"
        ]),
        // 允许 login/switchProfile/switchDid 的时候传入自定义参数
        ...Ko(c.extraParams || {}, [
          "autoConnect",
          "forceConnected",
          "saveConnect",
          "useSocket",
          "passkeyBehavior"
        ]),
        // baseUrl: state.baseUrl || props.baseUrl || '',
        // 注意 prefix 经过了特殊处理, 优先级高于 "...rest", 所以放在其后
        prefix: c.prefix,
        allowWallet: u(c.allowWallet) ? i.action !== "login" || ["1", "true", void 0, null].includes(globalThis.blocklet?.DID_CONNECT_ALLOW_WALLET) : c.allowWallet,
        onSuccess: async (...r) => {
          xo(i.action, ...r), Z(e?.onSuccess) && await e.onSuccess(...r), i.open = !1;
        },
        onClose(...r) {
          vo(i.action, ...r);
        },
        onError(r) {
          console.error(i.action, r), Oo(i.action, r, A.current);
        }
      };
      if (i.open = !0, ["login"].includes(i.action) && c.openMode === "window" && !(I.wallet || I.arcSphere))
        try {
          const r = {
            ...g,
            baseUrl: window.location.origin
          };
          ot(c.prefix) || (r.prefix = H(window.location.origin, n.serviceHost, c.prefix)), r.extraParams?.provider || (r.extraParams.provider = i?.user?.provider || "wallet"), await y.openPopup(r, { locale: P });
        } catch (r) {
          r instanceof Rt && j(), r.message === "Timeout" ? ae.error(je[P] || je.en) : console.error(r);
        }
      else
        y.open(g);
    }, Pe = f(async () => {
      const { params: e, url: o } = await ve();
      if (e) {
        const { switchBehavior: t, forceConnected: s, sourceAppPid: l, showClose: p } = e;
        s === i.user.did ? window.history.replaceState(null, "trim", o) : t === "required" ? ne(() => {
        }, {
          openMode: "redirect",
          redirect: o,
          sourceAppPid: l,
          forceConnected: s
        }) : t === "disabled" ? window.history.replaceState(null, "trim", o) : io.open({
          title: B.switchAccountDialog[P].title,
          content: /* @__PURE__ */ K(Vo, { children: [
            /* @__PURE__ */ m(Jo, { variant: "body1", sx: { textAlign: "center", mb: 2 }, children: B.switchAccountDialog[P].description }),
            /* @__PURE__ */ K($, { sx: { display: "flex", alignItems: "center", color: "grey.A700" }, children: [
              /* @__PURE__ */ K(
                $,
                {
                  sx: {
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    gap: 1.5,
                    lineHeight: 1
                  },
                  children: [
                    /* @__PURE__ */ m(Ee, { did: i.user.did, shape: "circle", variant: "circle", size: 80 }),
                    /* @__PURE__ */ m(_e, { did: i.user.did, showAvatar: !1, compact: !0, responsive: !1 }),
                    B.switchAccountDialog[P].currentAccount
                  ]
                }
              ),
              /* @__PURE__ */ m($, { sx: { display: "flex", justifyContent: "center", px: 2 }, children: /* @__PURE__ */ m(
                $,
                {
                  component: st,
                  icon: ct,
                  sx: {
                    fontSize: 24,
                    color: to.grey[400],
                    animation: "right 2.5s linear infinite",
                    "@keyframes right": {
                      "0%": {
                        transform: "translateX(-3px)",
                        opacity: 0
                      },
                      "60%": {
                        transform: "translateX(3px)",
                        opacity: 1
                      },
                      "100%": {
                        transform: "translateX(0px)",
                        opacity: 0
                      }
                    }
                  }
                }
              ) }),
              /* @__PURE__ */ K(
                $,
                {
                  sx: {
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    gap: 1.5,
                    lineHeight: 1,
                    fontWeight: 500
                  },
                  children: [
                    /* @__PURE__ */ m(Ee, { did: s, shape: "circle", variant: "circle", size: 80 }),
                    /* @__PURE__ */ m(_e, { did: s, showAvatar: !1, compact: !0, responsive: !1 }),
                    B.switchAccountDialog[P].nextAccount
                  ]
                }
              )
            ] })
          ] }),
          showCloseButton: p,
          showCancelButton: !1,
          confirmButtonText: B.switchAccountDialog[P].confirm,
          async onConfirm(g) {
            const w = (await Se()).find((T) => T.userDid === s);
            if (w) {
              re(w).then((T) => {
                ee(
                  {
                    connected_did: w.user.did,
                    connected_pk: w.user.pk,
                    connected_wallet_os: w.extra.walletOS,
                    connected_app: oe()
                  },
                  !0
                ), x({ ...T, encrypted: !1 }), C({ showProgress: !0 }).then(async () => {
                  await E(200), d.emit(a.LOGIN, T, _, A.current), O(A.current), await W();
                }).catch((Ce) => {
                  throw d.emit(a.LOGIN_FAILED, Ce), Ce;
                });
              }), g();
              return;
            }
            ne(
              () => {
                g(), window.location.replace(o);
              },
              { sourceAppPid: l, forceConnected: s, enableSwitchApp: !1 },
              { showQuickConnect: !0 }
            );
          }
        });
      }
    }), Uo = f(async (e, o) => {
      const t = Object.assign(
        {
          login: !0,
          bindWallet: !0,
          bindDidSpaces: !1
        },
        o?.requirements
      ), s = o?.openMode || "popup";
      t.login && await N(), t.bindWallet && await new Promise((l) => {
        ge(() => {
          l();
        });
      }), t.bindDidSpaces && (await Fe(i?.user) || await new Promise((l) => {
        t.bindDidSpaces === "full" ? W({
          onSuccess() {
            l();
          }
        }) : t.bindDidSpaces === "read" && me({
          onSuccess() {
            l();
          }
        });
      })), s === "window" ? y.openPopup(e, o) : s === "popup" && y.open(e);
    });
    le(() => {
      const e = Number(i.unReadCount || 0);
      fe(e);
    }, [i.unReadCount]);
    const Mo = f(() => {
      U.get("magicToken") && U.delete("magicToken"), U.toString() && window.history.replaceState({}, "", `${window.location.pathname}?${U.toString()}`);
    }), Ae = f((e) => new Promise((o, t) => {
      y.open({
        action: "login",
        locale: P,
        prefix: c.prefix,
        useSocket: !1,
        messages: {
          title: P === "zh" ? "验证 MagicLink Token" : "Verify MagicLink Token"
        },
        magicToken: e,
        onSuccess(...s) {
          V(...s), Mo(), o();
        },
        onError(s) {
          d.emit(a.LOGIN_FAILED, s), t(s);
        }
      });
    })), Ho = {
      ...i,
      loading: c.autoConnect && !i.user || i.loading,
      openDidConnect: Uo,
      login: ie,
      logout: he,
      switchDid: ne,
      autoSwitchDid: Pe,
      refreshProfile: bo,
      switchProfile: Co,
      switchPassport: To,
      connectToDidSpaceForImport: me,
      connectToDidSpaceForFullAccess: W,
      bindWallet: ge,
      refresh: C,
      updateConnectedInfo: ee,
      // federated relates
      federatedMaster: Ro,
      // oauth relates
      useOAuth: Tt,
      OAuthProvider: Ne,
      OAuthConsumer: Ct,
      OAuthContext: bt,
      // passkey relates
      usePasskey: It,
      PasskeyProvider: We,
      PasskeyConsumer: yt,
      PasskeyContext: kt,
      // user related
      useDid: Lt,
      WrapDid: _t,
      getUserSessions: Se,
      async loginUserSession(e) {
        try {
          const o = await re(e);
          ee(
            {
              connected_did: e.user.did,
              connected_pk: e.user.pk,
              connected_wallet_os: e.extra.walletOS,
              connected_app: oe()
            },
            !0
          ), x({ ...o, encrypted: !1 }), await C({ showProgress: !0 }), await E(200), d.emit(a.LOGIN, o, _, A.current), O(A.current), await W();
        } catch (o) {
          throw d.emit(a.LOGIN_FAILED, o), o;
        }
      },
      unReadCount: eo,
      setUnReadCount: fe,
      verifyMagicToken: Ae,
      // 二次认证相关方法
      withSecondaryAuth: mo
    }, A = De(Ho), Go = {
      api: lo,
      events: d,
      storage: Y,
      connectApi: y,
      session: A.current
    }, ce = {
      login: V,
      "switch-profile": Eo,
      "switch-passport": se,
      "switch-passport-failed": Io,
      "bind-wallet": Do,
      "bind-wallet-failed": _o,
      "login-failed": Lo
    };
    le(() => {
      if (i.initialized) {
        const e = !no;
        if (d.emit("change", { user: Te(i.user), isFirst: e }), i.user && globalThis.blocklet) {
          const o = {
            did: i.user.did,
            host: window.location.host,
            appPid: globalThis.blocklet.appPid,
            visitorId: q(),
            sourceAppPid: i.user.sourceAppPid,
            fullName: i.user.fullName
          };
          h("bridge callArc: onChange", {
            isFirst: e,
            user: o
          }), b.callArc("onChange", {
            ...o,
            user: o,
            isFirst: e
          });
        }
      }
    }, [i.user, i.initialized, d]), le(() => {
      i.initialized && i.user && Pe();
    }, [i.initialized]), nt(async () => {
      const e = (r) => {
        ht(r.encrypted) && (r.encrypted = !1), window.temporaryDIDConnectOnSuccess instanceof Function ? (h("bridgeOnLogin: temporaryDIDConnectOnSuccess", { result: r }), window.temporaryDIDConnectOnSuccess(r, (w) => w)) : (h("bridgeOnLogin: onLogin", { result: r }), V(r));
      };
      if (b.registerBlocklet("callLoginOAuth", (r) => {
        h("bridge registerBlocklet: callLoginOAuth", r), y.loginOAuth({
          ...r,
          onLogin: e
        });
      }), b.registerBlocklet("logout", he), b.registerBlocklet("login", (r) => {
        h("bridge registerBlocklet: login", r), e(r);
      }), tt(), !q()) {
        if (I.arcSphere) {
          h("bridge callArc: getVisitorId");
          const r = await b.callArc("getVisitorId");
          h("bridge callArc: getVisitorId result", { walletVisitorId: r }), ke(r);
        } else if (I.wallet) {
          const r = await Ut();
          ke(r);
        }
      }
      const t = qo.get("connected_app"), s = oe();
      if (n.autoDisconnect && t && s && t !== s) {
        xe("[clearSession] createSessionContext -> SessionProvider -> useMount: autoDisconnect", {
          autoDisconnect: n.autoDisconnect,
          connectedApp: t,
          actualApp: s
        }), ue(), i.initialized = !0, c.autoConnect ? F() : j();
        return;
      }
      const l = po();
      if (window?.self === window?.parent) {
        let r = "web";
        if (I.mobile.apple.device ? r = "ios" : I.mobile.android.device && (r = "android"), I.wallet && Mt({ version: I.walletVersion, platform: r }) && !l)
          try {
            i.loading = !0;
            const w = await Ht();
            if (w) {
              await V({
                sessionToken: w.sessionToken,
                refreshToken: w.refreshToken,
                csrfToken: w.csrfToken,
                visitorId: w.visitorId,
                encrypted: !1
              }), i.initialized = !0;
              return;
            }
          } catch (w) {
            throw d.emit(a.LOGIN_FAILED, w), w;
          } finally {
            i.loading = !1;
          }
      }
      const p = U.get("magicToken");
      if (p)
        try {
          i.initialized = !0, await Ae(p);
        } catch (r) {
          console.error("verifyMagicToken failed", r);
        }
      if (l) {
        await C({ showProgress: !0 }), i.initialized = !0, i.user && await W();
        return;
      }
      if (typeof window < "u") {
        const r = new URL(window.location.href), w = r.searchParams.get("loginToken");
        if (w) {
          x({ loginToken: w, encrypted: !1 }), r.searchParams.delete("loginToken"), window.history.replaceState({}, window.title, r.href);
          return;
        }
      }
      if (fo()) {
        await co(!0), i.initialized = !0;
        return;
      }
      if (i.initialized = !0, c.autoConnect ? F() : j(), I.arcSphere && ![
        // 不应该唤起自动登录的路由
        H(G, "login"),
        H(G, "connect"),
        H(G, "lost-passport")
      ].includes(window.location.pathname) && !l)
        try {
          h("bridge callArc: autoLogin");
          const r = await b.callArc("autoLogin");
          h("bridgecallArc: autoLogin result", r), r && await V({
            sessionToken: r.sessionToken,
            refreshToken: r.refreshToken,
            csrfToken: r.csrfToken,
            visitorId: r.visitorId,
            encrypted: !1
          });
        } catch (r) {
          d.emit(a.LOGIN_FAILED, r), Oe.error("Failed to autoLogin ArcSphere", r);
        }
    });
    const zo = U.has("popup");
    if (Fo() && !i.initialized)
      return /* @__PURE__ */ m(it, { children: zo ? null : /* @__PURE__ */ m(Zo, {}) });
    const be = {
      locale: P,
      onSwitchPassport: ({ sessionToken: e, refreshToken: o, csrfToken: t }) => se({ sessionToken: e, refreshToken: o, csrfToken: t, encrypted: !1 }),
      onUnbindOAuth: () => C(),
      onBindOAuth: () => C(),
      onAddPasskey: () => C(),
      onRemovePasskey: () => C(),
      session: A.current
    };
    return /* @__PURE__ */ m($t, { value: Go, children: /* @__PURE__ */ m(We, { ...be, children: /* @__PURE__ */ K(Ne, { ...be, children: [
      !i.open && typeof n.children == "function" ? n.children(i) : n.children,
      Ze,
      ro,
      yo,
      k.rolling && /* @__PURE__ */ m(Re, { callback: () => ao() }),
      /* @__PURE__ */ m(Re, { callback: so })
    ] }) }) });
  }
  pe.propTypes = {
    children: S.any.isRequired,
    serviceHost: S.string,
    action: S.string,
    prefix: S.string,
    appendAuthServicePrefix: S.bool,
    locale: S.string,
    timeout: S.number,
    autoConnect: S.bool,
    // should we open connect dialog when session not found
    autoDisconnect: S.bool,
    // should we auto disconnect on appId mismatch
    useSocket: S.bool,
    // should we auto disconnect on appId mismatch
    extraParams: S.object,
    options: S.object,
    webWalletUrl: S.string,
    protectedRoutes: S.arrayOf(S.string),
    apiOptions: S.object,
    lazyRefreshToken: S.bool
  };
  function Je(L) {
    return function(n) {
      return /* @__PURE__ */ m(ye, { children: /* @__PURE__ */ m(Ve, { children: (y) => /* @__PURE__ */ m(L, { ...n, ...y }) }) });
    };
  }
  return {
    SessionProvider: (L) => /* @__PURE__ */ m(ye, { children: /* @__PURE__ */ m(Vt, { children: /* @__PURE__ */ m(pe, { ...L }) }) }),
    SessionConsumer: Ve,
    SessionContext: qe,
    withSession: Je
  };
}
function Qi({ storageEngine: X = "cookie" } = {}) {
  const Q = Xe, te = Qe;
  let k = null;
  if (typeof window < "u" && (k = (globalThis.blocklet || {}).componentId), X === "cookie") {
    let D = "/", O = 1;
    if (typeof window < "u") {
      const Y = window.env || {}, z = window.blocklet || {};
      D = Y.groupPathPrefix || z.groupPrefix || z.prefix || "", D = D.replace(/\/+$/, ""), D = D || "/", z.serverVersion && (O = Pt(window.blocklet?.settings?.session?.cacheTtl, 1 / 24));
    }
    return $e(
      Q,
      "cookie",
      {
        path: D,
        returnDomain: !1,
        expireInDays: O
      },
      {
        appendAuthServicePrefix: !0,
        extraParams: { componentId: k },
        refreshTokenStorageKey: te
      }
    );
  }
  if (X === "localStorage")
    return $e(Q, "ls", {}, !0);
  throw new Error("storageEngine must be cookie or localStorage");
}
export {
  a as EVENTS,
  qe as SessionContext,
  Mt as checkEnableAutoLogin,
  Qi as createAuthServiceSessionContext,
  $e as createSessionContext,
  $e as default,
  Fe as didSpacesIsRequired,
  Ut as getMobileVisitorId,
  Ht as login,
  Zi as loginFederatedMaster,
  er as mountFederatedIframe,
  B as translations
};
