import { jsx as _jsx } from "react/jsx-runtime";
/**
 * Auth React integration for @agentuity/auth.
 *
 * All React-specific code for auth.
 * Import from '@agentuity/auth/react' for React components and hooks.
 *
 * @module agentuity/react
 */
import { useEffect, createContext, useContext, useState, useMemo } from 'react';
import { createAuthClient as createBetterAuthClient } from 'better-auth/react';
import { organizationClient } from 'better-auth/client/plugins';
import { apiKeyClient } from '@better-auth/api-key/client';
/**
 * Get the default client plugins for auth.
 *
 * These mirror the server-side plugins:
 * - organizationClient: Multi-tenancy support
 * - apiKeyClient: Programmatic API key management
 *
 * Note: jwt() and bearer() are server-only plugins.
 */
export function getDefaultClientPlugins() {
    return [organizationClient(), apiKeyClient()];
}
/**
 * Create a pre-configured Auth client.
 *
 * This factory provides sensible defaults for Agentuity projects:
 * - Uses `/api/auth` as the default base path
 * - Automatically uses `window.location.origin` as base URL in browsers
 * - Includes organization and API key plugins by default
 *
 * @example Basic usage (zero config)
 * ```typescript
 * import { createAuthClient } from '@agentuity/auth/react';
 *
 * export const authClient = createAuthClient();
 * export const { signIn, signUp, signOut, useSession, getSession } = authClient;
 * ```
 *
 * @example With custom base path
 * ```typescript
 * export const authClient = createAuthClient({
 *   basePath: '/auth', // If mounted at /auth instead of /api/auth
 * });
 * ```
 *
 * @example With additional plugins
 * ```typescript
 * import { twoFactorClient } from 'better-auth/client/plugins';
 *
 * export const authClient = createAuthClient({
 *   plugins: [twoFactorClient()],
 * });
 * ```
 *
 * @example With custom plugins only (no defaults)
 * ```typescript
 * import { organizationClient } from 'better-auth/client/plugins';
 *
 * export const authClient = createAuthClient({
 *   skipDefaultPlugins: true,
 *   plugins: [organizationClient()],
 * });
 * ```
 */
export function createAuthClient(options) {
    const baseURL = options?.baseURL ?? (typeof window !== 'undefined' ? window.location.origin : '');
    const basePath = options?.basePath ?? '/api/auth';
    const defaultPlugins = options?.skipDefaultPlugins ? [] : getDefaultClientPlugins();
    const userPlugins = options?.plugins ?? [];
    // Merge default plugins with user plugins
    // We pass through the full options to preserve type inference
    // The return type preserves plugin type inference via the generic parameter
    //
    // The plugins array uses a type assertion because bun's package resolution can create
    // multiple physical copies of @better-auth/core with different dependency tree hashes,
    // causing TypeScript to treat structurally identical types as incompatible.
    return createBetterAuthClient({
        ...options,
        baseURL,
        basePath,
        plugins: [...defaultPlugins, ...userPlugins],
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
    });
}
const AuthContext = createContext(null);
/**
 * Auth provider component.
 *
 * This component manages authentication state and can optionally:
 * - Set auth headers for API calls via `onAuthHeaderChange`
 * - Report loading state via `onAuthLoadingChange`
 * - Identify users for analytics via `onIdentify`
 *
 * @example Basic usage
 * ```tsx
 * import { createAuthClient, AuthProvider } from '@agentuity/auth/react';
 *
 * const authClient = createAuthClient();
 *
 * <AuthProvider authClient={authClient}>
 *   <App />
 * </AuthProvider>
 * ```
 *
 * @example With auth header injection for API calls
 * ```tsx
 * import { createAuthClient, AuthProvider } from '@agentuity/auth/react';
 *
 * const authClient = createAuthClient();
 *
 * function App() {
 *   const [authHeader, setAuthHeader] = useState<string | null>(null);
 *
 *   // Use authHeader in your API client
 *   const apiClient = useMemo(() => createApiClient({ authHeader }), [authHeader]);
 *
 *   return (
 *     <AuthProvider authClient={authClient} onAuthHeaderChange={setAuthHeader}>
 *       <MyApp apiClient={apiClient} />
 *     </AuthProvider>
 *   );
 * }
 * ```
 *
 * @example With analytics integration
 * ```tsx
 * import { getAnalytics } from '@agentuity/frontend';
 *
 * <AuthProvider
 *   authClient={authClient}
 *   onIdentify={(userId, traits) => getAnalytics().identify(userId, traits)}
 * >
 * ```
 */
export function AuthProvider({ children, authClient, refreshInterval = 3600000, tokenEndpoint = '/token', onAuthHeaderChange, onAuthLoadingChange, onIdentify, }) {
    const [user, setUser] = useState(null);
    const [session, setSession] = useState(null);
    const [isPending, setIsPending] = useState(true);
    const [error, setError] = useState(null);
    useEffect(() => {
        const fetchAuthState = async () => {
            try {
                onAuthLoadingChange?.(true);
                setIsPending(true);
                setError(null);
                // Use the auth client's getSession method
                const result = await authClient.getSession();
                if (result.data?.user) {
                    const authUser = result.data.user;
                    setUser(authUser);
                    setSession(result.data.session ?? null);
                    // Identify user for analytics (if callback provided)
                    onIdentify?.(authUser.id, {
                        email: authUser.email || '',
                        name: authUser.name || '',
                    });
                    // Get the JWT token for API calls (unless disabled)
                    if (tokenEndpoint !== false) {
                        try {
                            const tokenResult = await authClient.$fetch(tokenEndpoint, { method: 'GET' });
                            const tokenData = tokenResult.data;
                            if (tokenData?.token) {
                                onAuthHeaderChange?.(`Bearer ${tokenData.token}`);
                            }
                            else {
                                onAuthHeaderChange?.(null);
                            }
                        }
                        catch {
                            // Token endpoint might not exist, that's okay
                            onAuthHeaderChange?.(null);
                        }
                    }
                    else {
                        onAuthHeaderChange?.(null);
                    }
                }
                else {
                    setUser(null);
                    setSession(null);
                    onAuthHeaderChange?.(null);
                }
            }
            catch (err) {
                console.error('[AuthProvider] Failed to get auth state:', err);
                setError(err instanceof Error ? err : new Error('Failed to get auth state'));
                setUser(null);
                setSession(null);
                onAuthHeaderChange?.(null);
            }
            finally {
                onAuthLoadingChange?.(false);
                setIsPending(false);
            }
        };
        fetchAuthState();
        const interval = setInterval(fetchAuthState, refreshInterval);
        return () => clearInterval(interval);
    }, [
        authClient,
        refreshInterval,
        tokenEndpoint,
        onAuthHeaderChange,
        onAuthLoadingChange,
        onIdentify,
    ]);
    const contextValue = useMemo(() => ({
        authClient,
        user,
        session,
        isPending,
        error,
        isAuthenticated: !isPending && user !== null,
    }), [authClient, user, session, isPending, error]);
    return _jsx(AuthContext.Provider, { value: contextValue, children: children });
}
/**
 * Hook to access Auth state.
 *
 * This hook provides access to the current user and session.
 * Must be used within an AuthProvider.
 *
 * @example
 * ```tsx
 * import { useAuth } from '@agentuity/auth/react';
 *
 * function Profile() {
 *   const { user, session, isPending, isAuthenticated } = useAuth();
 *
 *   if (isPending) return <div>Loading...</div>;
 *   if (!isAuthenticated) return <div>Not signed in</div>;
 *
 *   return <div>Welcome, {user.name}!</div>;
 * }
 * ```
 */
export function useAuth() {
    const context = useContext(AuthContext);
    if (!context) {
        throw new Error('useAuth must be used within an AuthProvider');
    }
    return context;
}
//# sourceMappingURL=react.js.map