'use client';
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
// packages/ui/src/routing/AuthGuard.tsx
/**
 * @fileoverview AuthGuard component
 * @description Protects routes based on authentication configuration
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
import { useEffect, useState, lazy, Suspense, } from 'react';
import { Spinner, Stack } from '@donotdev/components';
import { useAuthConfig, FEATURE_STATUS, USER_ROLES, SUBSCRIPTION_TIERS, } from '@donotdev/core';
// Platform-specific hooks via conditional exports
import { useRedirectGuard, useNavigate } from '@donotdev/ui/routing/hooks';
import { useAuthSafe } from '../utils/useAuthSafe';
// Lazy load consent component for auth routes
const CookieConsent = lazy(() => import('../components/cookie-consent/CookieConsent'));
/**
 * AuthGuard component that protects routes based on authentication config
 *
 * 🎯 SINGLE SOURCE OF TRUTH: Only uses @donotdev/core, never directly calls auth
 *
 * Role System (from store):
 * - 'guest': No authentication
 * - 'user': Authenticated Firebase user
 * - 'admin': Authenticated user with Firebase custom claim isAdmin: true
 *
 * Subscription System (from store):
 * - 'free': Basic features
 * - 'pro': Professional features
 * - 'premium': Premium features
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function AuthGuard({ auth, children, fallback: Fallback = () => _jsx(Spinner, { overlay: true }), }) {
    const navigate = useNavigate();
    const user = useAuthSafe('user');
    const can = useAuthSafe('can');
    const status = useAuthSafe('status');
    const [slowWarning, setSlowWarning] = useState(false);
    // Check if redirect should happen BEFORE rendering fallback
    const { shouldRedirect, redirectTo, isChecking } = useRedirectGuard({
        auth,
    });
    useEffect(() => {
        // Soft timeout at 5 seconds - show warning, don't force redirect
        // Firebase auth typically resolves in 200ms-800ms (broadband), 1-3s (cold start)
        const timer = setTimeout(() => {
            if (status === FEATURE_STATUS.INITIALIZING) {
                setSlowWarning(true);
                if (process.env.NODE_ENV === 'development') {
                    console.warn('[AuthGuard] Auth taking longer than usual (>5s)');
                }
            }
        }, 5000);
        return () => clearTimeout(timer);
    }, [status]);
    // Redirect if needed
    useEffect(() => {
        if (shouldRedirect && redirectTo) {
            navigate(redirectTo, { replace: true });
        }
    }, [shouldRedirect, redirectTo, navigate]);
    // Public route - no auth required
    if (auth === false) {
        return _jsx(_Fragment, { children: children });
    }
    // Early return: show loader if redirect will happen or checking auth state
    // This prevents content flash before redirect
    if (shouldRedirect || isChecking) {
        return _jsx(Spinner, { overlay: true });
    }
    // Show slow auth warning after 5s timeout (only if not redirecting)
    if (status === FEATURE_STATUS.INITIALIZING && slowWarning) {
        return (_jsx(Stack, { align: "center", justify: "center", style: { padding: 'var(--gap-md)', minHeight: '100vh' }, children: _jsxs("div", { className: "dndev-w-full", style: { maxWidth: '28rem', textAlign: 'center' }, children: [_jsx("h2", { style: { marginBottom: 'var(--gap-md)' }, children: "Loading is taking longer than usual" }), _jsx("p", { style: {
                            marginBottom: 'var(--gap-md)',
                            color: 'var(--muted-foreground)',
                        }, children: "This might be due to a slow connection. Please wait or try refreshing the page." }), _jsx("button", { onClick: () => window.location.reload(), style: {
                            padding: 'var(--gap-sm) var(--gap-md)',
                            backgroundColor: 'var(--primary)',
                            color: 'var(--primary-foreground)',
                            border: 'none',
                            borderRadius: 'var(--radius)',
                            cursor: 'pointer',
                        }, children: "Refresh Page" })] }) }));
    }
    // Still checking auth state (but not redirecting) - show fallback
    if (status === FEATURE_STATUS.INITIALIZING) {
        return _jsx(Fallback, {});
    }
    // Check if it's a consent issue (no functional cookies for auth)
    // This is a special case where we don't redirect, but show consent UI
    if (auth &&
        typeof auth === 'object' &&
        auth.required &&
        !user &&
        can &&
        !can.navigate(auth)) {
        return (_jsx(Stack, { align: "center", justify: "center", style: { padding: 'var(--gap-md)', minHeight: '100vh' }, children: _jsxs("div", { className: "dndev-w-full", style: { maxWidth: '28rem' }, children: [_jsx("h2", { style: { marginBottom: 'var(--gap-md)' }, children: "Authentication Required" }), _jsx("p", { style: { marginBottom: 'var(--gap-md)' }, children: "This page requires authentication. Please accept functional cookies to continue." }), _jsx(Suspense, { fallback: _jsx("div", { children: "Loading consent..." }), children: _jsx(CookieConsent, {}) })] }) }));
    }
    // All checks passed, render children
    return _jsx(_Fragment, { children: children });
}
/**
 * Hook to check if current user can navigate to a route with given auth config
 * ONLY uses store - single source of truth!
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function useCanNavigate(auth) {
    const can = useAuthSafe('can');
    return can?.navigate(auth) ?? false;
}
/**
 * @deprecated Use useCanNavigate instead
 */
export const useCanAccess = useCanNavigate;
/**
 * Hook to get current user's role - directly from store
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function useUserRole() {
    const user = useAuthSafe('user');
    const role = user?.role;
    return (role || USER_ROLES.GUEST);
}
/**
 * Hook to check specific role - directly from store
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function useHasRole(role) {
    const user = useAuthSafe('user');
    // Use cached role for display purposes
    return user?.role === role;
}
/**
 * Hook to get all auth state for debugging
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function useAuthState() {
    const user = useAuthSafe('user');
    const userSubscription = useAuthSafe('userSubscription');
    const loading = useAuthSafe('loading');
    return {
        authenticated: !!user,
        role: user?.role,
        tier: userSubscription?.tier || 'free',
        loading,
        userId: user?.id,
    };
}
/**
 * HOC to wrap components with auth protection
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function withAuth(Component, auth) {
    const WrappedComponent = (props) => (_jsx(AuthGuard, { auth: auth, children: _jsx(Component, { ...props }) }));
    return WrappedComponent;
}
/**
 * Utility to create auth configs
 *
 * @version 0.0.3
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export const createAuthConfig = {
    /** No authentication required */
    public: () => false,
    /** Basic authentication required */
    required: () => ({ required: true }),
    /** User role (any authenticated user) */
    user: () => ({
        required: true,
        role: USER_ROLES.USER,
    }),
    /** Admin role (Firebase custom claim isAdmin: true) */
    admin: () => ({
        required: true,
        role: USER_ROLES.ADMIN,
    }),
    /** Tier-based authentication */
    tier: (tier) => ({
        required: true,
        tier,
    }),
    /** Pro tier */
    pro: () => ({
        required: true,
        tier: SUBSCRIPTION_TIERS.PRO,
    }),
    /** Premium tier */
    premium: () => ({
        required: true,
        tier: SUBSCRIPTION_TIERS.PREMIUM,
    }),
    /** Admin with pro tier requirement */
    adminPro: () => ({
        required: true,
        role: USER_ROLES.ADMIN,
        tier: SUBSCRIPTION_TIERS.PRO,
    }),
    /** Custom validation */
    custom: (validate) => ({
        required: true,
        validate,
    }),
};
export default AuthGuard;
