import { useState as g, useCallback as c, useMemo as E, useEffect as T } from "react";
import { useAuth as $ } from "./use-auth.js";
import { useConfig as j } from "../provider/config-provider.js";
function N() {
  return typeof window < "u" && "navigator" in window && "credentials" in navigator && "create" in navigator.credentials && "get" in navigator.credentials;
}
async function J() {
  if (!N()) return !1;
  try {
    return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
  } catch {
    return !1;
  }
}
function A(s) {
  const e = s.replace(/-/g, "+").replace(/_/g, "/"), a = e.padEnd(e.length + (4 - e.length % 4) % 4, "="), l = atob(a), f = new ArrayBuffer(l.length), u = new Uint8Array(f);
  for (let o = 0; o < l.length; o++)
    u[o] = l.charCodeAt(o);
  return f;
}
function w(s) {
  const e = new Uint8Array(s);
  let a = "";
  for (let l = 0; l < e.byteLength; l++)
    a += String.fromCharCode(e[l]);
  return btoa(a).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
}
function M(s) {
  return {
    ...s,
    challenge: A(s.challenge),
    user: {
      ...s.user,
      id: A(s.user.id)
    },
    excludeCredentials: s.excludeCredentials?.map((e) => ({
      ...e,
      id: A(e.id)
    }))
  };
}
function V(s) {
  return {
    ...s,
    challenge: A(s.challenge),
    allowCredentials: s.allowCredentials?.map((e) => ({
      ...e,
      id: A(e.id)
    }))
  };
}
function L(s) {
  const e = s.response, a = {
    id: s.id,
    rawId: w(s.rawId),
    type: s.type,
    response: {
      clientDataJSON: w(e.clientDataJSON)
    }
  };
  return e instanceof AuthenticatorAttestationResponse ? a.response.attestationObject = w(e.attestationObject) : e instanceof AuthenticatorAssertionResponse && (a.response.authenticatorData = w(e.authenticatorData), a.response.signature = w(e.signature), e.userHandle && (a.response.userHandle = w(e.userHandle))), a;
}
function K() {
  const { user: s, sdk: e } = $(), { apiUrl: a, publishableKey: l, features: f } = j(), [u, o] = g([]), [m, n] = g(!1), [k, y] = g(null), [W, D] = g(!1), p = E(() => N(), []), b = E(() => f.passkeys, [f.passkeys]), d = c((t) => {
    const r = {
      code: t.code || "UNKNOWN_ERROR",
      message: t.message || "An unknown error occurred",
      details: t.details,
      field: t.field
    };
    throw y(r), r;
  }, []), C = c(async () => {
    if (!p) return !1;
    try {
      const t = await J();
      return D(t), t;
    } catch {
      return D(!1), !1;
    }
  }, [p]), h = c(async () => {
    if (!(!e.user || !s || !b))
      try {
        n(!0), y(null);
        const t = await e.user.getPasskeys({ fields: [] });
        o(t.data || []);
      } catch (t) {
        console.error("Failed to load passkeys:", t), y({
          code: "PASSKEYS_LOAD_FAILED",
          message: "Failed to load passkeys"
        });
      } finally {
        n(!1);
      }
  }, [e.user, s, b]);
  T(() => {
    C(), h();
  }, [C, h]);
  const S = c(async (t) => {
    if (!e.user) throw new Error("User not authenticated");
    if (!p) throw new Error("WebAuthn not supported");
    if (!b) throw new Error("Passkeys not enabled");
    try {
      n(!0), y(null);
      const r = await e.auth.beginPasskeyRegistration({
        name: t || `Passkey ${u.length + 1}`
      }), i = M(r.options);
      return {
        challenge: r.challenge,
        options: i,
        sessionId: r.sessionId
      };
    } catch (r) {
      return d(r);
    } finally {
      n(!1);
    }
  }, [e.auth, p, b, u.length, d]), v = c(async (t, r) => {
    if (!e.user) throw new Error("User not authenticated");
    try {
      n(!0), y(null);
      const i = L(r), O = {
        sessionId: t.sessionId,
        credential: i
      }, P = await e.auth.finishPasskeyRegistration(O);
      return await h(), P.passkey;
    } catch (i) {
      return d(i);
    } finally {
      n(!1);
    }
  }, [e.user, h, d]), F = c(async (t) => {
    const r = await S(t);
    try {
      const i = await navigator.credentials.create({
        publicKey: r.options
      });
      if (!i)
        throw new Error("Failed to create credential");
      return await v(r, i);
    } catch (i) {
      throw i.name === "NotAllowedError" ? new Error("User cancelled the registration process") : i.name === "InvalidStateError" ? new Error("This authenticator is already registered") : new Error(`Registration failed: ${i.message}`);
    }
  }, [S, v]), I = c(async () => {
    if (!e.auth) throw new Error("User not authenticated");
    if (!p) throw new Error("WebAuthn not supported");
    try {
      n(!0), y(null);
      const t = await e.auth.beginPasskeyAuthentication({}), r = V(t.options);
      return {
        challenge: t.challenge,
        options: r,
        sessionId: t.sessionId
      };
    } catch (t) {
      return d(t);
    } finally {
      n(!1);
    }
  }, [e.auth, p, d]), R = c(async (t, r) => {
    if (!e.user) throw new Error("User not authenticated");
    try {
      n(!0), y(null);
      const i = L(r), O = {
        sessionId: t.sessionId,
        credential: i
      }, P = await e.auth.finishPasskeyAuthentication(O);
      return {
        success: !0,
        session: P.session,
        user: P.user
      };
    } catch (i) {
      return {
        success: !1,
        error: i.message
      };
    } finally {
      n(!1);
    }
  }, [e.auth, d]), _ = c(async () => {
    const t = await I();
    try {
      const r = await navigator.credentials.get({
        publicKey: t.options
      });
      if (!r)
        throw new Error("Failed to get credential");
      return await R(t, r);
    } catch (r) {
      return r.name === "NotAllowedError" ? {
        success: !1,
        error: "User cancelled the authentication process"
      } : {
        success: !1,
        error: `Authentication failed: ${r.message}`
      };
    }
  }, [I, R]), U = c(async (t, r) => {
    if (!e.user) throw new Error("User not authenticated");
    try {
      n(!0), y(null);
      const i = await e.user.updatePasskey(t, r);
      return await h(), i.passkey;
    } catch (i) {
      return d(i);
    } finally {
      n(!1);
    }
  }, [e.user, h, d]), z = c(async (t) => {
    if (!e.user) throw new Error("User not authenticated");
    try {
      n(!0), y(null), await e.user.deletePasskey(t), await h();
    } catch (r) {
      d(r);
    } finally {
      n(!1);
    }
  }, [e.user, h, d]), B = c(async (t, r) => U(t, { name: r }), [U]), q = c(async () => {
    await h();
  }, [h]), x = E(() => u.find((t) => t.isPrimary) || u[0] || null, [u]), H = E(() => u.length, [u]);
  return {
    // Passkey state
    passkeys: u,
    isSupported: p,
    isAvailable: W,
    isLoaded: !!s && b,
    isLoading: m,
    error: k,
    // Passkey registration
    beginRegistration: S,
    finishRegistration: v,
    registerPasskey: F,
    // Passkey authentication
    beginAuthentication: I,
    finishAuthentication: R,
    authenticateWithPasskey: _,
    // Passkey management
    updatePasskey: U,
    deletePasskey: z,
    renamePasskey: B,
    // Passkey information
    primaryPasskey: x,
    passkeyCount: H,
    // Utility methods
    refreshPasskeys: q,
    checkSupport: C
  };
}
function X() {
  const {
    registerPasskey: s,
    isSupported: e,
    isAvailable: a,
    isLoading: l,
    error: f
  } = K(), [u, o] = g("idle");
  return {
    register: c(async (n) => {
      if (!e || !a)
        throw o("error"), new Error("Passkeys not supported or available");
      try {
        o("registering");
        const k = await s(n);
        return o("success"), k;
      } catch (k) {
        throw o("error"), k;
      }
    }, [s, e, a]),
    state: u,
    isSupported: e,
    isAvailable: a,
    isLoading: l,
    error: f,
    canRegister: e && a && !l
  };
}
function Z() {
  const {
    authenticateWithPasskey: s,
    isSupported: e,
    isAvailable: a,
    isLoading: l,
    error: f
  } = K(), [u, o] = g("idle");
  return {
    authenticate: c(async () => {
      if (!e || !a)
        throw o("error"), new Error("Passkeys not supported or available");
      try {
        o("authenticating");
        const n = await s();
        return n.success ? o("success") : o("error"), n;
      } catch (n) {
        throw o("error"), n;
      }
    }, [s, e, a]),
    state: u,
    isSupported: e,
    isAvailable: a,
    isLoading: l,
    error: f,
    canAuthenticate: e && a && !l
  };
}
export {
  Z as usePasskeyAuthentication,
  X as usePasskeyRegistration,
  K as usePasskeys
};
//# sourceMappingURL=use-passkeys.js.map
