"use client";

import React from "react";
import { useRouter } from "next/navigation";

import { getMe } from "@/lib/frontend/apiClient";
import { buildLoginUrl, LOGIN_REASONS } from "@/lib/frontend/authRedirect";

import { AuthProvider as AuthContextProvider } from "@/components/auth/authContext";

/**
 * AuthProvider (RHL-020)
 *
 * Responsibilities:
 * - Run a session check via GET /api/auth/me.
 * - Store the result in AuthContext.
 * - Redirect to /login when unauthenticated (reason=expired, next=current URL).
 *
 * Important UX improvement:
 * - We no longer render full-screen "solo spinners" here.
 * - The AppShell stays visible and AuthGate renders the loading/error UI inside main content.
 *
 * Important performance/UX improvement:
 * - We do NOT re-check the session on every route change.
 * - The session check runs:
 *   - once on mount
 *   - and again only when the user hits "retry"
 *
 * @param {{ children: React.ReactNode }} props
 */
export default function AuthProvider({ children }) {
	const router = useRouter();

	// Prevent double redirects in quick re-renders.
	const didRedirectRef = React.useRef(false);

	// Auth state exposed via context.
	const [auth, setAuth] = React.useState({
		status: "loading",
		user: null,
		error: null,
	});

	// Retry tick triggers a refetch without tying auth checks to route changes.
	const [retryTick, setRetryTick] = React.useState(0);

	const retry = React.useCallback(() => {
		setRetryTick((n) => n + 1);
	}, []);

	React.useEffect(() => {
		let cancelled = false;

		async function runSessionCheck() {
			setAuth({ status: "loading", user: null, error: null });

			try {
				const res = await getMe();
				if (cancelled) return;

				if (res?.user) {
					// Authenticated session.
					didRedirectRef.current = false;
					setAuth({ status: "authenticated", user: res.user, error: null });
					return;
				}

				// Unauthenticated session (frontend-friendly endpoint returns 200 + user:null).
				setAuth({ status: "unauthenticated", user: null, error: null });

				if (!didRedirectRef.current) {
					didRedirectRef.current = true;

					// Preserve the current URL as "next" so the user returns to the same page after login.
					const next =
						typeof window !== "undefined"
							? `${window.location.pathname}${window.location.search}`
							: "/";

					const loginUrl = buildLoginUrl({
						reason: LOGIN_REASONS.EXPIRED,
						next,
					});

					router.replace(loginUrl);
				}
			} catch (err) {
				if (cancelled) return;

				setAuth({
					status: "error",
					user: null,
					error: "Sitzung konnte nicht geprüft werden. Bitte erneut versuchen.",
				});
			}
		}

		runSessionCheck();

		return () => {
			cancelled = true;
		};
	}, [router, retryTick]);

	return (
		<AuthContextProvider value={{ ...auth, retry }}>
			{children}
		</AuthContextProvider>
	);
}
