import * as React from 'react';
import { useAdminAuth } from '../hooks/useAdminAuth';
import { Spinner } from '@/components/ui/spinner';
import { getAuthToken } from '@/lib/apiClient';

/**
 * Wraps every authenticated admin page. Redirects to /admin/login if there's
 * no session once the initial /auth/me hydration finishes, and blocks
 * rendering while that check is in flight to avoid a flash of protected UI.
 */
export function RequireAuth({ children }: { children: React.ReactNode }) {
    const { user, loading } = useAdminAuth();
    const [hasToken, setHasToken] = React.useState(() =>
        Boolean(getAuthToken()),
    );

    React.useEffect(() => {
        const syncToken = () => setHasToken(Boolean(getAuthToken()));
        // `pageshow` runs when the browser restores a protected page from its
        // back/forward cache after logout.
        window.addEventListener('pageshow', syncToken);
        window.addEventListener('storage', syncToken);
        window.addEventListener('admin-auth-changed', syncToken);
        return () => {
            window.removeEventListener('pageshow', syncToken);
            window.removeEventListener('storage', syncToken);
            window.removeEventListener('admin-auth-changed', syncToken);
        };
    }, []);

    React.useEffect(() => {
        if (
            (!hasToken || (!loading && !user)) &&
            window.location.pathname !== '/admin/login'
        ) {
            // A browser-back restore may happen before Inertia has rebuilt its
            // page state. Use a native replacement so the redirect never
            // depends on Inertia's transient router state.
            window.location.replace('/admin/login');
        }
    }, [hasToken, loading, user]);

    if (
        loading ||
        !hasToken ||
        (!user && window.location.pathname !== '/admin/login')
    ) {
        return (
            <div className="flex min-h-screen items-center justify-center bg-(--color-bg)">
                <Spinner className="h-6 w-6 text-(--color-accent)" />
            </div>
        );
    }

    return <>{children}</>;
}
