import { useState as k, useMemo as o, useCallback as p, useEffect as E } from "react";
import { FrankSession as z } from "@frank-auth/sdk";
import { useAuth as B } from "./use-auth.js";
import { useConfig as G } from "../provider/config-provider.js";
function g() {
  const { session: e, createSession: r, reload: n, userType: u } = B(), { apiUrl: l, publishableKey: c } = G(), [t, S] = k([]), [A, a] = k(!1), [D, v] = k(null), i = o(() => e?.accessToken ? new z({
    publishableKey: c,
    apiUrl: l,
    userType: u ?? "end_user"
  }, e.accessToken) : null, [c, l, e?.accessToken]), f = p((s) => {
    const w = {
      code: s.code || "UNKNOWN_ERROR",
      message: s.message || "An unknown error occurred",
      details: s.details,
      field: s.field
    };
    throw v(w), w;
  }, []), h = p(async () => {
    if (i)
      try {
        a(!0), v(null);
        const s = await i.listSessions();
        S(s.data);
      } catch (s) {
        console.error("Failed to load sessions:", s), v({
          code: "SESSIONS_LOAD_FAILED",
          message: "Failed to load sessions"
        });
      } finally {
        a(!1);
      }
  }, [i]);
  E(() => {
    h();
  }, [h]);
  const I = p(async (s) => r(s), [r]), T = p(async (s) => {
    if (!i) throw new Error("Session not available");
    try {
      a(!0), v(null), i.setActiveSession(s), await n(), await h();
    } catch (w) {
      f(w);
    } finally {
      a(!1);
    }
  }, [i, n, h, f]), b = p(async () => {
    if (!i) throw new Error("Session not available");
    try {
      a(!0), v(null);
      const s = await i.refreshSession();
      return await n(), s;
    } catch (s) {
      return f(s), null;
    } finally {
      a(!1);
    }
  }, [i, n, f]), U = p(async (s) => {
    if (!i) throw new Error("Session not available");
    try {
      a(!0), v(null), await i.revokeSession(s), s === e?.id ? await n() : await h();
    } catch (w) {
      f(w);
    } finally {
      a(!1);
    }
  }, [i, e?.id, n, h, f]), M = p(async (s = !1) => {
    if (!i) throw new Error("Session not available");
    try {
      a(!0), v(null), await i.revokeAllSessions({
        exceptCurrent: s
      }), s ? await h() : await n();
    } catch (w) {
      f(w);
    } finally {
      a(!1);
    }
  }, [i, n, h, f]), C = p(async () => {
    if (!i) throw new Error("Session not available");
    try {
      a(!0), v(null), await n();
    } catch (s) {
      f(s);
    } finally {
      a(!1);
    }
  }, [i, n, f]), m = o(() => e?.id || null, [e]), L = o(() => e?.accessToken || null, [e]), d = o(
    () => e?.expiresAt ? new Date(e.expiresAt) : null,
    [e]
  ), F = o(
    () => e?.lastActiveAt ? new Date(e.lastActiveAt) : null,
    [e]
  ), N = o(() => !!e && !e.expired, [e]), x = o(() => d ? d.getTime() <= Date.now() : !1, [d]), O = o(() => {
    if (!d) return !1;
    const s = Date.now() + 5 * 60 * 1e3;
    return d.getTime() <= s && !x;
  }, [d, x]), R = o(() => {
    if (!d) return null;
    const s = d.getTime() - Date.now();
    return Math.max(0, Math.floor(s / 6e4));
  }, [d]), y = o(() => e?.deviceInfo ? {
    userAgent: e.deviceInfo.userAgent || "",
    browser: e.deviceInfo.browser || "Unknown",
    os: e.deviceInfo.os || "Unknown",
    device: e.deviceInfo.device || "Unknown",
    ipAddress: e.deviceInfo.ipAddress || "",
    location: e.deviceInfo.location
  } : null, [e]), _ = o(() => !e || !y ? !1 : typeof navigator < "u" && y.userAgent === navigator.userAgent, [e, y]), K = o(
    () => e?.trustedDevice || !1,
    [e]
  ), W = o(() => t.length > 1, [t]), j = o(() => t.length, [t]), q = o(
    () => t.filter((s) => s.id !== m),
    [t, m]
  );
  return {
    // Session state
    session: e,
    sessions: t,
    isLoaded: !!e,
    isLoading: A,
    error: D,
    // Session management
    createSession: I,
    setActiveSession: T,
    refreshSession: b,
    revokeSession: U,
    revokeAllSessions: M,
    endSession: C,
    // Session information
    sessionId: m,
    sessionToken: L,
    expiresAt: d,
    lastActiveAt: F,
    // Session status
    isActive: N,
    isExpired: x,
    isExpiring: O,
    timeUntilExpiry: R,
    // Device information
    deviceInfo: y,
    // Security features
    isCurrentDevice: _,
    isTrustedDevice: K,
    // Multi-session support
    hasMultipleSessions: W,
    sessionCount: j,
    otherSessions: q
  };
}
function V() {
  const {
    isActive: e,
    isExpired: r,
    isExpiring: n,
    timeUntilExpiry: u,
    expiresAt: l,
    refreshSession: c
  } = g();
  return {
    isActive: e,
    isExpired: r,
    isExpiring: n,
    timeUntilExpiry: u,
    expiresAt: l,
    refreshSession: c,
    status: r ? "expired" : n ? "expiring" : e ? "active" : "inactive"
  };
}
function X() {
  const {
    sessions: e,
    sessionCount: r,
    otherSessions: n,
    hasMultipleSessions: u,
    revokeSession: l,
    revokeAllSessions: c,
    setActiveSession: t,
    isLoading: S,
    error: A
  } = g();
  return {
    sessions: e,
    sessionCount: r,
    otherSessions: n,
    hasMultipleSessions: u,
    revokeSession: l,
    revokeAllSessions: c,
    setActiveSession: t,
    isLoading: S,
    error: A,
    revokeAllOthers: () => c(!0)
  };
}
function Y() {
  const {
    deviceInfo: e,
    isCurrentDevice: r,
    isTrustedDevice: n,
    sessionId: u,
    lastActiveAt: l
  } = g();
  return {
    deviceInfo: e,
    isCurrentDevice: r,
    isTrustedDevice: n,
    sessionId: u,
    lastActiveAt: l,
    isSecure: n && r
  };
}
function Z(e = {}) {
  const {
    autoRefresh: r = !1,
    refreshThreshold: n = 5,
    onExpiry: u,
    onExpiring: l
  } = e, {
    isExpired: c,
    isExpiring: t,
    timeUntilExpiry: S,
    refreshSession: A
  } = g();
  return E(() => {
    r && t && S && S <= n && A().catch(console.error);
  }, [r, t, S, n, A]), E(() => {
    c && u?.();
  }, [c, u]), E(() => {
    t && l?.();
  }, [t, l]), {
    isExpired: c,
    isExpiring: t,
    timeUntilExpiry: S,
    refreshSession: A,
    autoRefresh: r
  };
}
export {
  X as useMultiSession,
  g as useSession,
  Z as useSessionExpiry,
  Y as useSessionSecurity,
  V as useSessionStatus
};
//# sourceMappingURL=use-session.js.map
