import { jsxs as z, jsx as O } from "react/jsx-runtime";
import y from "prop-types";
import J from "lodash/isUndefined";
import { use as K, createContext as W } from "react";
import u from "@arcblock/ux/lib/Toast";
import { useReactive as g, useMemoizedFn as i, useCreation as q } from "ahooks";
import w from "lodash/noop";
import { joinURL as S } from "ufo";
import { translate as G } from "@arcblock/ux/lib/Locale/util";
import { BLOCKLET_SERVICE_PATH_PREFIX as H } from "@arcblock/ux/lib/Util/constant";
import { getBlockletData as X, getFederatedEnabled as $, getMaster as Q } from "@arcblock/ux/lib/Util/federated";
import { startRegistration as Y, startAuthentication as Z } from "@simplewebauthn/browser";
import { createAxios as ee, getWebAuthnErrorMessage as h, logger as U, getApiErrorMessage as A } from "../utils.js";
import { parseResponse as se, PassportSwitcher as te } from "../components/PassportSwitcher.js";
import F from "../Connect/assets/locale.js";
const E = W({}), { Provider: re, Consumer: ve } = E, ae = {
  zh: {
    ...F.zh,
    cancel: "取消",
    usePasskey: "使用 Passkey",
    createPasskey: "新建 Passkey",
    creatingPasskey: "创建 Passkey...",
    connectPasskey: "绑定 Passkey",
    nonePasskey: "未配置 Passkey 方式",
    connectPasskeySucceed: "Passkey 绑定成功",
    disconnectPasskeySucceed: "Passkey 解绑成功",
    verifyPasskeyFailed: "Passkey 验证失败",
    connectPasskeyFailed: "Passkey 绑定失败",
    disconnectPasskeyFailed: "Passkey 解绑失败",
    createPasskeyDesc1: "Passkey 是一种密码替代品，使用指纹、面部识别、设备密码或 PIN 验证您的身份。",
    createPasskeyDesc2: "Passkey 可以用于登录、验证，作为您账户简单且安全的替代方案。",
    emailPlaceholder: "请输入邮箱以作为备用",
    verifyButton: "验证邮箱",
    sendCodeButton: "获取验证码",
    codeSentMessage: "我们已向 {email} 发送验证码，验证码将在 30 分钟内有效，请检查您的邮箱或垃圾邮件文件夹。",
    codeSentSuccess: "验证码发送成功",
    noPassports: "没有可更换的通行证",
    cancelAuth: "取消授权",
    emailInvalid: "邮箱格式不正确",
    webauthn: {
      error: {
        canceled: "身份验证已被取消",
        security: "身份验证过程中出现安全错误",
        notSupported: "当前浏览器不支持 Passkey 身份验证",
        aborted: "身份验证已被中止"
      }
    }
  },
  en: {
    ...F.en,
    cancel: "Cancel",
    usePasskey: "Use Existing Passkey",
    createPasskey: "Create New Passkey",
    creatingPasskey: "Creating Passkey...",
    connectPasskey: "Connect Passkey",
    nonePasskey: "Passkey is not configured",
    connectPasskeySucceed: "Passkey add succeed",
    disconnectPasskeySucceed: "Passkey remove succeed",
    verifyPasskeyFailed: "Passkey verify failed",
    connectPasskeyFailed: "Passkey add failed",
    disconnectPasskeyFailed: "Passkey remove failed",
    createPasskeyDesc1: "Passkeys are a password replacement that validates your identity using touch, facial recognition, a device password, or a PIN.",
    createPasskeyDesc2: "Passkeys can be used for sign-in, verification as a simple and secure alternative to your account.",
    emailPlaceholder: "Enter your email address",
    verifyButton: "Verify Email",
    sendCodeButton: "Get Verify Code",
    codeSentMessage: "We just sent a verification code to {email}, the code will be valid for 30 minutes, please check your inbox or spam folder.",
    codeSentSuccess: "Verification code sent successfully",
    noPassports: "No passports to switch",
    cancelAuth: "Cancel authentication",
    emailInvalid: "Invalid email address",
    webauthn: {
      error: {
        canceled: "Authentication was canceled",
        security: "A security error occurred during authentication",
        notSupported: "This browser does not support passkey authentication",
        aborted: "Authentication was aborted"
      }
    }
  }
};
function ne({
  children: m,
  locale: l = "en",
  onAddPasskey: C = w,
  onRemovePasskey: I = w,
  onSwitchPassport: R = w,
  session: x = null
}) {
  const v = S(window.env?.apiPrefix || H, "/api/passkey"), r = g({
    baseUrl: "/",
    session: void 0,
    connecting: !1,
    disconnecting: !1,
    targetAppPid: void 0
  }), o = g({
    open: !1,
    currentUser: null,
    passports: [],
    selectedPassport: void 0,
    reset() {
      o.open = !1, o.currentUser = null, o.passports = [], o.selectedPassport = void 0;
    }
  }), d = g({
    user: null,
    loading: !1,
    creating: !1,
    verifying: !1,
    creatingStatus: "",
    verifyingStatus: "",
    error: "",
    email: "",
    code: "",
    verified: !window?.blocklet?.settings?.kyc?.email,
    sent: !1,
    openDialog: !1,
    get status() {
      return this.creating || this.verifying ? "scanned" : this.creatingStatus === "succeed" || this.verifyingStatus === "succeed" ? "succeed" : this.creatingStatus === "error" || this.verifyingStatus === "error" ? "error" : "";
    },
    reset() {
      d.creating = !1, d.verifying = !1, d.creatingStatus = "", d.verifyingStatus = "", d.error = "";
    }
  }), n = i((t, e = {}) => G(ae, t, l, "en", e)), c = q(() => ee({ baseURL: S(r.baseUrl, v), sessionTokenKey: "__sst", timeout: 60 * 1e3 }), [r.baseUrl, v]), B = i(async () => {
    if (r.baseUrl === "/")
      return window.blocklet;
    try {
      if (new URL(r.baseUrl).host === window.location.host)
        return window.blocklet;
    } catch {
    }
    return await X(r.baseUrl);
  }), P = window?.blocklet?.componentId, T = (t) => {
    r.baseUrl = t || "/";
  }, M = (t) => {
    r.targetAppPid = t;
  }, b = i(async (t) => {
    const { data: e } = await c.get("/register", { params: t });
    console.warn("passkey.create.options", e);
    try {
      const s = await Y({ optionsJSON: e, useAutoRegister: !1 });
      console.warn("passkey.create.response", s);
      const { data: a } = await c.post("/register", s, { params: { challenge: e.challenge } });
      if (console.warn("passkey.create.result", a), !a.verified)
        throw new Error(n("createPasskeyFailed"));
      return a;
    } catch (s) {
      throw console.error("passkey.create.error", s), s.name ? new Error(h(s, n("createPasskeyFailed"), n)) : s;
    }
  }), k = i(async (t) => {
    const { data: e } = await c.get("/auth", { params: t });
    console.warn("passkey.auth.options", e);
    try {
      const s = await Z({ optionsJSON: e });
      console.warn("passkey.auth.response", s);
      const { data: a } = await c.post("/auth", s, {
        params: { challenge: e.challenge, targetAppPid: r.targetAppPid }
      });
      if (console.warn("passkey.auth.result", a), !a.verified)
        throw new Error(n("verifyPasskeyFailed"));
      return a;
    } catch (s) {
      throw console.error("passkey.auth.error", s), s.name ? new Error(h(s, n("verifyPasskeyFailed"), n)) : s;
    }
  }), D = async (t) => {
    r.connecting = !0;
    try {
      const e = await b({
        ...t,
        locale: l,
        componentId: P
      });
      return u.success(n("connectPasskeySucceed")), C(e), e;
    } catch (e) {
      U.error("Failed to connect passkey", e), u.error(A(e, n("connectPasskeyFailed")));
    } finally {
      r.connecting = !1;
    }
  }, N = async ({ session: t, connectedAccount: e }) => {
    r.session = t, r.disconnecting = !0;
    try {
      const s = await k({
        action: "disconnect",
        locale: l,
        componentId: P,
        sourceAppPid: t?.user?.sourceAppPid,
        credentialId: e.id
      });
      u.success(n("disconnectPasskeySucceed")), I(s);
    } catch (s) {
      U.error("Failed to disconnect passkey", s), u.error(A(s, n("disconnectPasskeyFailed")));
    } finally {
      r.disconnecting = !1;
    }
  }, j = async (t = {}) => {
    try {
      const { data: e } = await c.get("/passports");
      e.length ? (o.open = !0, o.currentUser = t, o.passports = e || []) : u.error(n("noPassports"));
    } catch (e) {
      u.error(e.message || n("getPassportFailed"));
    }
  }, L = i((...t) => {
    o.reset(), R(...t);
  }), _ = i(async ({ action: t = "login", ...e } = {}) => {
    const s = r.baseUrl;
    if (e?.sourceAppPid === window.blocklet?.appPid)
      r.baseUrl = window.blocklet?.appUrl || "/";
    else if (e?.sourceAppPid) {
      const a = await B(), p = $(a), f = Q(a);
      p && f?.appPid && e?.sourceAppPid === f?.appPid && (r.baseUrl = f.appUrl);
    }
    try {
      const a = {
        ...e,
        action: t,
        locale: l,
        componentId: P
      };
      J(a.inviter) && window.localStorage.getItem("inviter") && (a.inviter = window.localStorage.getItem("inviter"));
      const p = se(await k(a));
      return p.provider = "passkey", p;
    } catch (a) {
      console.error("passkey.login.error", a);
      const p = h(a, n("verifyPasskeyFailed"), n);
      throw r.baseUrl = s, new Error(p);
    }
  }), V = i(() => {
  });
  return /* @__PURE__ */ z(
    re,
    {
      value: {
        api: c,
        locale: l,
        connectPasskey: D,
        disconnectPasskey: N,
        createPasskey: b,
        verifyPasskey: k,
        loginPasskey: _,
        logoutPasskey: V,
        switchPassport: j,
        baseUrl: r.baseUrl,
        setBaseUrl: T,
        setTargetAppPid: M,
        passkeyState: d,
        disconnecting: r.disconnecting,
        connecting: r.connecting,
        t: n
      },
      children: [
        m,
        /* @__PURE__ */ O(
          te,
          {
            api: c,
            locale: l,
            switchState: o,
            onSwitchPassport: L,
            session: x
          }
        )
      ]
    }
  );
}
function be() {
  return K(E);
}
ne.propTypes = {
  children: y.node.isRequired,
  locale: y.string,
  onAddPasskey: y.func,
  onRemovePasskey: y.func,
  onSwitchPassport: y.func,
  session: y.object
};
export {
  ve as PasskeyConsumer,
  E as PasskeyContext,
  ne as PasskeyProvider,
  be as usePasskey
};
