'use client';
import { jsx as W } from "react/jsx-runtime";
import { createContext as $, useReducer as J, useMemo as p, useCallback as l, useEffect as Q, useContext as X } from "react";
import { AuthSDK as Y, OrganizationSDK as j, SessionSDK as K, UserSDK as ee, FrankAuthError as te } from "@frank-auth/sdk";
const O = $(null);
function ae(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 {
        ...N,
        isLoaded: !0
      };
    default:
      return i;
  }
}
const N = {
  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
  },
  // @ts-expect-error
  sdk: void 0
};
function ie({
  children: i,
  publishableKey: s,
  userType: c = "external",
  apiUrl: y,
  secretKey: h,
  projectId: f,
  initialState: R,
  onError: _,
  onSignIn: A,
  onSignOut: T,
  debug: d = !1
}) {
  const [I, a] = J(ae, {
    ...N,
    ...R
  }), r = p(() => new Y({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: d,
    userType: c,
    projectId: f,
    secretKey: h
  }), [s, y, d]), E = p(() => new j({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: d,
    userType: c,
    projectId: f,
    secretKey: h
  }), [s, y, d]), S = p(() => new K({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: d,
    userType: c,
    projectId: f,
    secretKey: h
  }), [s, y, d]), w = p(() => new ee({
    publishableKey: s,
    apiUrl: y,
    enableDevMode: d,
    userType: c,
    projectId: f,
    secretKey: h
  }), [s, y, d]), k = p(() => ({
    auth: r,
    organization: E,
    session: S,
    user: w
  }), [w, r, E, S]), 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 }), _?.(e), d && console.error("[FrankAuth] Error:", e);
    },
    [_, d]
  ), g = 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 E.getOrganization(o);
            a({ type: "SET_ORGANIZATION", payload: u }), a({ type: "SET_ACTIVE_ORGANIZATION", payload: u });
            const H = await E.listMembers(o);
            a({ type: "SET_MEMBERSHIPS", payload: H.data });
          } catch (o) {
            d && console.warn(
              "[FrankAuth] Failed to load organization:",
              o
            );
          }
        const e = await L(
          t.user,
          I.organization,
          c
        );
        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, c, d, n]), L = 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;
    }
  }, m = 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 }), A?.(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 te ? e.message : "Sign in failed"
          }
        };
      } finally {
        a({ type: "SET_LOADING", payload: !1 });
      }
    },
    [r, A, n]
  ), D = 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: c,
          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 }), A?.(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, A, n]
  ), v = l(async () => {
    try {
      a({ type: "SET_LOADING", payload: !0 }), await r.signOut({ logoutAll: !1 }), r.authStorage.clearAll(), a({ type: "RESET_STATE" }), T?.();
    } catch (t) {
      n(t);
    } finally {
      a({ type: "SET_LOADING", payload: !1 });
    }
  }, [r, T, n]), z = l(
    async (t) => {
      try {
        S.activeSession = t;
        const e = await S.getCurrentSession();
        return a({ type: "SET_SESSION", payload: e }), e;
      } catch (e) {
        throw n(e), e;
      }
    },
    [r, n]
  ), G = l(
    async (t) => {
      try {
        if (t.session) {
          const e = t.session;
          typeof t.session == "string" && (S.activeSession = t.session, await S.getCurrentSession()), a({ type: "SET_SESSION", payload: e });
        }
        if (t.organization) {
          const e = typeof t.organization == "string" ? await E.getOrganization(t.organization) : t.organization;
          a({ type: "SET_ACTIVE_ORGANIZATION", payload: e });
        }
      } catch (e) {
        n(e);
      }
    },
    [r, n]
  ), M = l(
    async (t) => {
      try {
        let e;
        typeof t == "string" ? e = await E.getOrganization(t) : e = t, a({ type: "SET_ACTIVE_ORGANIZATION", payload: e });
      } catch (e) {
        n(e);
      }
    },
    [r, n]
  ), C = l(
    async (t) => {
      try {
        a({ type: "SET_LOADING", payload: !0 });
        const e = await r.switchOrganization(t);
        a({ type: "SET_ACTIVE_ORGANIZATION", payload: e }), await g();
      } catch (e) {
        n(e);
      } finally {
        a({ type: "SET_LOADING", payload: !1 });
      }
    },
    [r, n, g]
  ), 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]
  ), P = l(async () => {
    try {
      await w.deleteUser(), a({ type: "RESET_STATE" }), T?.();
    } catch (t) {
      n(t);
    }
  }, [r, n, T]), q = 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]
  ), x = 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]
  ), V = 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]
  ), Z = 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]
  ), b = l(async () => {
    await g();
  }, [g]);
  Q(() => {
    g();
  }, [g]);
  const B = {
    // State
    ...I,
    // Methods
    signIn: m,
    signUp: D,
    signOut: v,
    createSession: z,
    setActive: G,
    setActiveOrganization: M,
    switchOrganization: C,
    updateUser: U,
    deleteUser: P,
    reload: b,
    requestPasswordReset: q,
    resetPassword: F,
    validateToken: Z,
    resendVerification: x,
    verifyIdentity: V,
    sdk: k
  };
  return /* @__PURE__ */ W(O.Provider, { value: B, children: i });
}
function re() {
  const i = X(O);
  if (!i)
    throw new Error("useAuth must be used within an AuthProvider");
  return i;
}
function le() {
  const { isLoaded: i, isSignedIn: s, user: c } = re();
  return {
    isLoaded: i,
    isSignedIn: s,
    user: c,
    isAuthenticated: i && s,
    requireAuth: () => {
      if (!i)
        throw new Error("Authentication not loaded");
      if (!s)
        throw new Error("Authentication required");
    }
  };
}
export {
  O as AuthContext,
  ie as AuthProvider,
  re as useAuth,
  le as useAuthGuard
};
//# sourceMappingURL=auth-provider.js.map
