'use client';
import { jsx as H } from "react/jsx-runtime";
import { createContext as W, useReducer as $, useMemo as h, useCallback as l, useEffect as J, useContext as Q } from "react";
import { FrankAuth as X, FrankOrganization as Y, FrankSession as j, FrankUser as K, FrankAuthError as ee } from "@frank-auth/sdk";
const I = W(null);
function te(i, s) {
  switch (s.type) {
    case "SET_LOADING":
      return { ...i, isLoading: s.payload };
    case "SET_LOADED":
      return { ...i, isLoaded: s.payload };
    case "SET_USER":
      return {
        ...i,
        user: s.payload,
        isSignedIn: !!s.payload,
        error: null
      };
    case "SET_SESSION":
      return {
        ...i,
        session: s.payload,
        error: null
      };
    case "SET_ORGANIZATION":
      return {
        ...i,
        organization: s.payload,
        error: null
      };
    case "SET_ACTIVE_ORGANIZATION":
      return {
        ...i,
        activeOrganization: s.payload,
        error: null
      };
    case "SET_MEMBERSHIPS":
      return {
        ...i,
        organizationMemberships: s.payload,
        error: null
      };
    case "SET_FEATURES":
      return {
        ...i,
        features: s.payload
      };
    case "SET_ERROR":
      return {
        ...i,
        error: s.payload,
        isLoading: !1
      };
    case "RESET_STATE":
      return {
        ...O,
        isLoaded: !0
      };
    default:
      return i;
  }
}
const O = {
  isLoaded: !1,
  isLoading: !1,
  isSignedIn: !1,
  user: null,
  session: null,
  organization: null,
  organizationMemberships: [],
  activeOrganization: null,
  error: null,
  features: {
    signUp: !0,
    signIn: !0,
    passwordReset: !0,
    mfa: !1,
    passkeys: !1,
    oauth: !1,
    magicLink: !1,
    sso: !1,
    organizationManagement: !1,
    userProfile: !0,
    sessionManagement: !0
  }
};
function oe({
  children: i,
  publishableKey: s,
  userType: d = "external",
  apiUrl: y,
  secretKey: g,
  projectId: f,
  initialState: N,
  onError: T,
  onSignIn: p,
  onSignOut: A,
  debug: c = !1
}) {
  const [w, a] = $(te, {
    ...O,
    ...N
  }), r = h(() => new X({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: c,
    userType: d,
    projectId: f,
    secretKey: g
  }), [s, y, c]), S = h(() => new Y({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: c,
    userType: d,
    projectId: f,
    secretKey: g
  }), [s, y, c]), R = h(() => new j({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: c,
    userType: d,
    projectId: f,
    secretKey: g
  }), [s, y, c]), _ = h(() => new K({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: c,
    userType: d,
    projectId: f,
    secretKey: g
  }), [s, y, c]), n = l((t) => {
    const e = {
      code: t.code || "UNKNOWN_ERROR",
      message: t.message || "An unknown error occurred",
      details: t.details,
      field: t.field
    };
    a({ type: "SET_ERROR", payload: e }), T?.(e), c && console.error("[FrankAuth] Error:", e);
  }, [T, c]), E = l(async () => {
    try {
      a({ type: "SET_LOADING", payload: !0 });
      const t = await r.getAuthStatus();
      if (t.isAuthenticated && t.user) {
        if (a({ type: "SET_USER", payload: t.user }), a({ type: "SET_SESSION", payload: t.session }), f || t.user.organizationId)
          try {
            const o = f || t.user.organizationId || "", u = await S.getOrganization(o);
            a({ type: "SET_ORGANIZATION", payload: u }), a({ type: "SET_ACTIVE_ORGANIZATION", payload: u });
            const B = await S.listMembers(o);
            a({ type: "SET_MEMBERSHIPS", payload: B.data });
          } catch (o) {
            c && console.warn("[FrankAuth] Failed to load organization:", o);
          }
        const e = await k(t.user, w.organization, d);
        a({ type: "SET_FEATURES", payload: e });
      }
      a({ type: "SET_LOADED", payload: !0 });
    } catch (t) {
      n(t);
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, f, d, c, n]), k = async (t, e, o) => {
    const u = {
      signUp: !0,
      signIn: !0,
      passwordReset: !0,
      mfa: !1,
      passkeys: !1,
      oauth: !1,
      magicLink: !1,
      sso: !1,
      organizationManagement: !1,
      userProfile: !0,
      sessionManagement: !0
    };
    if (!t) return u;
    switch (o) {
      case "internal":
        return {
          ...u,
          mfa: !0,
          passkeys: !0,
          organizationManagement: !0,
          sso: !0
        };
      case "external":
        return {
          ...u,
          mfa: e?.settings?.mfaSettings?.enabled || !1,
          passkeys: e?.settings?.authConfig?.passkeysEnabled || !1,
          oauth: e?.settings?.authConfig?.oauthEnabled || !1,
          sso: e?.settings?.authConfig?.ssoEnabled || !1,
          organizationManagement: !0
        };
      case "end_user":
        return {
          ...u,
          mfa: e?.settings?.mfaSettings?.enabled || !1,
          passkeys: e?.settings?.authConfig?.passkeysEnabled || !1,
          oauth: e?.settings?.authConfig?.oauthEnabled || !1,
          organizationManagement: !1
        };
      default:
        return u;
    }
  }, L = l(async (t) => {
    try {
      a({ type: "SET_LOADING", payload: !0 }), a({ type: "SET_ERROR", payload: null });
      let e, o = "complete";
      switch (t.strategy) {
        case "password":
          if (!t.identifier || !t.password)
            throw new Error("Email/username and password are required");
          const u = {
            email: t.identifier,
            password: t.password,
            organizationId: t.organizationId,
            rememberMe: !0
          };
          e = await r.signIn(u), e.mfaRequired ? o = "needs_mfa" : e.verificationRequired && (o = "needs_verification");
          break;
        case "oauth":
          if (!t.provider)
            throw new Error("OAuth provider is required");
          e = await r.initiateOAuthLogin(t.provider, {
            redirectUrl: t.redirectUrl,
            organizationId: t.organizationId
          });
          break;
        case "magic_link":
          if (!t.identifier)
            throw new Error("Email is required for magic link");
          e = await r.sendMagicLink({
            email: t.identifier,
            redirectUrl: t.redirectUrl
            // organizationId: params.organizationId,
          });
          break;
        case "passkey":
          e = await r.beginPasskeyAuthentication({
            // todo fix
          }), o = "needs_passkey";
          break;
        case "sso":
          if (!t.organizationId)
            throw new Error("Organization ID is required for SSO");
          e = await r.initiateSSOLogin(t.organizationId, {
            redirectUrl: t.redirectUrl
          });
          break;
        default:
          throw new Error(`Unsupported sign-in strategy: ${t.strategy}`);
      }
      return e.user && e.session && (a({ type: "SET_USER", payload: e.user }), a({ type: "SET_SESSION", payload: e.session }), p?.(e.user)), {
        status: o,
        user: e.user,
        session: e.session,
        verificationId: e.verificationId,
        mfaToken: e.mfaToken
      };
    } catch (e) {
      return n(e), {
        status: "complete",
        error: {
          code: "SIGN_IN_FAILED",
          message: e instanceof ee ? e.message : "Sign in failed"
        }
      };
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, p, n]), m = l(async (t) => {
    try {
      a({ type: "SET_LOADING", payload: !0 }), a({ type: "SET_ERROR", payload: null });
      const e = {
        email: t.emailAddress,
        password: t.password,
        firstName: t.firstName,
        lastName: t.lastName,
        username: t.username,
        userType: d,
        acceptTerms: t.acceptTerms,
        marketingConsent: t.marketingConsent,
        phoneNumber: t.phoneNumber,
        locale: t.locale ?? "en",
        organizationId: t.organizationId,
        invitationToken: t.invitationToken,
        customAttributes: t.unsafeMetadata
      }, o = await r.signUp(e);
      o.user && o.session && (a({ type: "SET_USER", payload: o.user }), a({ type: "SET_SESSION", payload: o.session }), p?.(o.user));
      let u = "complete";
      return o.verificationRequired && (u = "needs_verification"), {
        status: u,
        user: o.user,
        session: o.session,
        verificationId: o.verificationToken
      };
    } catch (e) {
      return n(e), {
        status: "missing_requirements",
        error: {
          code: "SIGN_UP_FAILED",
          message: e instanceof Error ? e.message : "Sign up failed"
        }
      };
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, p, n]), z = l(async () => {
    try {
      a({ type: "SET_LOADING", payload: !0 }), await r.signOut({ logoutAll: !1 }), a({ type: "RESET_STATE" }), A?.();
    } catch (t) {
      n(t);
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, A, n]), D = l(async (t) => {
    try {
      const e = await r.createSession(t);
      return a({ type: "SET_SESSION", payload: e }), e;
    } catch (e) {
      throw n(e), e;
    }
  }, [r, n]), v = l(async (t) => {
    try {
      if (t.session) {
        const e = typeof t.session == "string" ? await r.setActiveSession(t.session) : t.session;
        a({ type: "SET_SESSION", payload: e });
      }
      if (t.organization) {
        const e = typeof t.organization == "string" ? await S.getOrganization(t.organization) : t.organization;
        a({ type: "SET_ACTIVE_ORGANIZATION", payload: e });
      }
    } catch (e) {
      n(e);
    }
  }, [r, n]), G = l(async (t) => {
    try {
      let e;
      typeof t == "string" ? e = await S.getOrganization(t) : e = t, a({ type: "SET_ACTIVE_ORGANIZATION", payload: e });
    } catch (e) {
      n(e);
    }
  }, [r, n]), M = l(async (t) => {
    try {
      a({ type: "SET_LOADING", payload: !0 });
      const e = await r.switchOrganization(t);
      a({ type: "SET_ACTIVE_ORGANIZATION", payload: e }), await E();
    } catch (e) {
      n(e);
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, n, E]), U = l(async (t) => {
    try {
      const e = await r.updateProfile(t);
      return a({ type: "SET_USER", payload: e }), e;
    } catch (e) {
      throw n(e), e;
    }
  }, [r, n]), C = l(async () => {
    try {
      await _.deleteUser(), a({ type: "RESET_STATE" }), A?.();
    } catch (t) {
      n(t);
    }
  }, [r, n, A]), P = l(async (t) => {
    try {
      return a({ type: "SET_LOADING", payload: !0 }), await r.requestPasswordReset(t);
    } catch (e) {
      throw n(e), e;
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, n]), F = l(async (t) => {
    try {
      return a({ type: "SET_LOADING", payload: !0 }), await r.resetPassword(t);
    } catch (e) {
      throw n(e), e;
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, n]), q = l(async (t) => {
    try {
      return a({ type: "SET_LOADING", payload: !0 }), await r.resendVerification(t);
    } catch (e) {
      throw n(e), e;
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, n]), x = l(async (t, e) => {
    try {
      return a({ type: "SET_LOADING", payload: !0 }), t === "phone" ? await r.verifyPhone(e) : await r.verifyEmail(e);
    } catch (o) {
      throw n(o), o;
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, n]), V = l(async (t) => {
    try {
      return a({ type: "SET_LOADING", payload: !0 }), await r.validateToken(t);
    } catch (e) {
      throw n(e), e;
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, n]), Z = l(async () => {
    await E();
  }, [E]);
  J(() => {
    E();
  }, [E]);
  const b = {
    // State
    ...w,
    // Methods
    signIn: L,
    signUp: m,
    signOut: z,
    createSession: D,
    setActive: v,
    setActiveOrganization: G,
    switchOrganization: M,
    updateUser: U,
    deleteUser: C,
    reload: Z,
    requestPasswordReset: P,
    resetPassword: F,
    validateToken: V,
    resendVerification: q,
    verifyIdentity: x,
    frankAuth: r,
    frankOrg: S,
    frankSess: R,
    frankUser: _
  };
  return /* @__PURE__ */ H(I.Provider, { value: b, children: i });
}
function ae() {
  const i = Q(I);
  if (!i)
    throw new Error("useAuth must be used within an AuthProvider");
  return i;
}
function ie() {
  const { isLoaded: i, isSignedIn: s, user: d } = ae();
  return {
    isLoaded: i,
    isSignedIn: s,
    user: d,
    isAuthenticated: i && s,
    requireAuth: () => {
      if (!i)
        throw new Error("Authentication not loaded");
      if (!s)
        throw new Error("Authentication required");
    }
  };
}
export {
  I as AuthContext,
  oe as AuthProvider,
  ae as useAuth,
  ie as useAuthGuard
};
//# sourceMappingURL=auth-provider.js.map
