import { useMemo as i, useState as E, useCallback as l, useEffect as V } from "react";
import { FrankUser as X } from "@frank-auth/sdk";
import { useAuth as Y } from "./use-auth.js";
import { useConfig as Z } from "../provider/config-provider.js";
const oe = {
  totp: {
    name: "Authenticator App",
    description: "Use an authenticator app like Google Authenticator or Authy",
    icon: "📱",
    setupSteps: [
      "Install an authenticator app on your phone",
      "Scan the QR code or enter the secret key",
      "Enter the 6-digit code from your app"
    ]
  },
  sms: {
    name: "SMS",
    description: "Receive codes via text message",
    icon: "💬",
    setupSteps: [
      "Enter your phone number",
      "Wait for the verification code",
      "Enter the code to confirm"
    ]
  },
  email: {
    name: "Email",
    description: "Receive codes via email",
    icon: "✉️",
    setupSteps: [
      "Confirm your email address",
      "Wait for the verification code",
      "Enter the code to confirm"
    ]
  },
  webauthn: {
    name: "Security Key",
    description: "Use a hardware security key or biometric authentication",
    icon: "🔐",
    setupSteps: [
      "Insert your security key or prepare biometric authentication",
      "Follow your browser's authentication prompts",
      "Confirm the registration"
    ]
  },
  backup_codes: {
    name: "Backup Codes",
    description: "Single-use codes for emergency access",
    icon: "🔢",
    setupSteps: [
      "Save these codes in a secure location",
      "Each code can only be used once",
      "Generate new codes when running low"
    ]
  }
};
function T() {
  const { user: a, session: m, reload: c, userType: y } = Y(), { apiUrl: w, publishableKey: h, features: M } = Z(), [o, p] = E([]), [F, v] = E([]), [q, s] = E(!1), [O, u] = E(null), t = i(() => m?.accessToken ? new X({
    publishableKey: h,
    apiUrl: w,
    userType: y ?? "end_user"
  }, m.accessToken) : null, [h, w, m?.accessToken]), d = i(() => M.mfa, [M.mfa]), n = l((e) => {
    const r = {
      code: e.code || "UNKNOWN_ERROR",
      message: e.message || "An unknown error occurred",
      details: e.details,
      field: e.field
    };
    throw u(r), r;
  }, []), f = l(async () => {
    if (!(!t || !a || !d))
      try {
        s(!0), u(null);
        const e = await t.getMFAMethods();
        if (p(e.data || []), a.mfaEnabled)
          try {
            const r = await t.getMFABackupCodes();
            v(r.codes || []);
          } catch (r) {
            console.warn("Could not load backup codes:", r);
          }
      } catch (e) {
        console.error("Failed to load MFA data:", e), u({
          code: "MFA_LOAD_FAILED",
          message: "Failed to load MFA data"
        });
      } finally {
        s(!1);
      }
  }, [t, a, d]);
  V(() => {
    f();
  }, [f]);
  const B = l(async () => {
    if (!t) throw new Error("User not authenticated");
    if (!d) throw new Error("MFA not available");
    try {
      s(!0), u(null);
      const e = {
        method: "totp"
      }, r = await t.setupMFA(e);
      return {
        method: "totp",
        qrCode: r.qrCode,
        secret: r.secret,
        backupCodes: r.backupCodes,
        verificationRequired: !0
      };
    } catch (e) {
      return n(e);
    } finally {
      s(!1);
    }
  }, [t, d, n]), L = l(async (e) => {
    if (!t) throw new Error("User not authenticated");
    if (!d) throw new Error("MFA not available");
    try {
      s(!0), u(null);
      const r = {
        method: "sms",
        phoneNumber: e
      }, b = await t.setupMFA(r);
      return {
        method: "sms",
        verificationRequired: !0
      };
    } catch (r) {
      return n(r);
    } finally {
      s(!1);
    }
  }, [t, d, n]), P = l(async (e) => {
    if (!t) throw new Error("User not authenticated");
    if (!d) throw new Error("MFA not available");
    try {
      s(!0), u(null);
      const r = {
        method: "email",
        email: e || a?.primaryEmailAddress
      }, b = await t.setupMFA(r);
      return {
        method: "email",
        verificationRequired: !0
      };
    } catch (r) {
      return n(r);
    } finally {
      s(!1);
    }
  }, [t, a, d, n]), _ = l(async () => {
    if (!t) throw new Error("User not authenticated");
    if (!d) throw new Error("MFA not available");
    try {
      s(!0), u(null);
      const e = {
        method: "webauthn"
      };
      return {
        method: "webauthn",
        challenge: (await t.setupMFA(e)).challenge,
        verificationRequired: !0
      };
    } catch (e) {
      return n(e);
    } finally {
      s(!1);
    }
  }, [t, d, n]), N = l(async (e, r, b) => {
    if (!t) throw new Error("User not authenticated");
    try {
      s(!0), u(null);
      const A = {
        method: e,
        code: r,
        methodId: b
      }, U = await t.verifyMFASetup(A);
      return await f(), await c(), U.method;
    } catch (A) {
      return n(A);
    } finally {
      s(!1);
    }
  }, [t, f, c, n]), I = l(async (e, r, b) => {
    if (!t) throw new Error("User not authenticated");
    try {
      s(!0), u(null);
      const A = {
        method: e,
        code: r,
        mfaToken: b,
        context: "login"
      };
      return await t.verifyMFA(A);
    } catch (A) {
      return n(A);
    } finally {
      s(!1);
    }
  }, [t, n]), W = l(async (e) => {
    if (!t) throw new Error("User not authenticated");
    try {
      s(!0), u(null), await t.removeMFAMethod(e), await f(), await c();
    } catch (r) {
      n(r);
    } finally {
      s(!1);
    }
  }, [t, f, c, n]), D = l(async (e) => {
    if (!t) throw new Error("User not authenticated");
    try {
      s(!0), u(null), await t.setPrimaryMFAMethod(e), await f();
    } catch (r) {
      n(r);
    } finally {
      s(!1);
    }
  }, [t, f, n]), x = l(async () => {
    if (!t) throw new Error("User not authenticated");
    try {
      s(!0), u(null);
      const e = await t.regenerateMFABackupCodes();
      return v(e.codes), e.codes;
    } catch (e) {
      return n(e);
    } finally {
      s(!1);
    }
  }, [t, n]), G = i(() => a?.mfaEnabled || !1, [a]), K = i(() => !1, []), H = i(() => o.find((e) => e.isPrimary) || null, [o]), g = i(
    () => o.some((e) => e.type === "totp"),
    [o]
  ), k = i(
    () => o.some((e) => e.type === "sms"),
    [o]
  ), S = i(
    () => o.some((e) => e.type === "email"),
    [o]
  ), C = i(
    () => o.some((e) => e.type === "webauthn"),
    [o]
  ), R = i(
    () => F.length > 0,
    [F]
  ), Q = i(() => {
    const e = [];
    return g && e.push("totp"), k && e.push("sms"), S && e.push("email"), C && e.push("webauthn"), R && e.push("backup_codes"), e;
  }, [g, k, S, C, R]), j = l(async () => {
    if (!t) throw new Error("User not authenticated");
    try {
      s(!0), u(null), await t.disableMFA(), p([]), v([]), await c();
    } catch (e) {
      n(e);
    } finally {
      s(!1);
    }
  }, [t, c, n]), z = l(async () => {
    if (!t) throw new Error("User not authenticated");
    try {
      s(!0), u(null), await t.enableMFA(), await c();
    } catch (e) {
      n(e);
    } finally {
      s(!1);
    }
  }, [t, c, n]), J = l(async () => {
    await f();
  }, [f]);
  return {
    // MFA state
    mfaMethods: o,
    isEnabled: G,
    isRequired: K,
    primaryMethod: H,
    backupCodes: F,
    isLoaded: !!a && d,
    isLoading: q,
    error: O,
    // MFA setup
    setupTOTP: B,
    setupSMS: L,
    setupEmail: P,
    setupWebAuthn: _,
    // MFA verification
    verifySetup: N,
    verifyMFA: I,
    // Method management
    removeMFAMethod: W,
    setPrimaryMethod: D,
    regenerateBackupCodes: x,
    // MFA status checking
    hasTOTP: g,
    hasSMS: k,
    hasEmail: S,
    hasWebAuthn: C,
    hasBackupCodes: R,
    // Method availability
    availableMethods: Q,
    // Convenience methods
    disable: j,
    enable: z,
    refreshMethods: J
  };
}
function se() {
  const {
    setupTOTP: a,
    verifySetup: m,
    hasTOTP: c,
    mfaMethods: y,
    removeMFAMethod: w,
    isLoading: h,
    error: M
  } = T(), o = i(
    () => y.find((p) => p.type === "totp"),
    [y]
  );
  return {
    isEnabled: c,
    method: o,
    setup: a,
    verify: (p) => m("totp", p),
    remove: o ? () => w(o.id) : void 0,
    isLoading: h,
    error: M
  };
}
function ne() {
  const {
    setupSMS: a,
    verifySetup: m,
    hasSMS: c,
    mfaMethods: y,
    removeMFAMethod: w,
    isLoading: h,
    error: M
  } = T(), o = i(
    () => y.find((p) => p.type === "sms"),
    [y]
  );
  return {
    isEnabled: c,
    method: o,
    setup: a,
    verify: (p) => m("sms", p),
    remove: o ? () => w(o.id) : void 0,
    phoneNumber: o?.phoneNumber || null,
    isLoading: h,
    error: M
  };
}
function ae() {
  const {
    backupCodes: a,
    regenerateBackupCodes: m,
    hasBackupCodes: c,
    isLoading: y,
    error: w
  } = T(), h = i(
    () => a.filter((o) => !o.used),
    [a]
  ), M = i(
    () => a.filter((o) => o.used),
    [a]
  );
  return {
    codes: a,
    unusedCodes: h,
    usedCodes: M,
    hasBackupCodes: c,
    regenerate: m,
    remainingCodes: h.length,
    totalCodes: a.length,
    isRunningLow: h.length <= 2,
    isLoading: y,
    error: w
  };
}
export {
  oe as MFA_METHOD_CONFIGS,
  ae as useBackupCodes,
  T as useMFA,
  ne as useSMSMFA,
  se as useTOTP
};
//# sourceMappingURL=use-mfa.js.map
