"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 / RHL-032)
 *
 * RHL-032 improvement:
 * - When revalidating while already authenticated, we keep:
 *   - status="authenticated"
 *   - user != null
 * - and only flip `isValidating=true`
 *
 * This prevents AuthGate from rendering the "Sitzung wird geprüft" content card
 * during fast navigations (branch switch), eliminating flicker.
 */
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,
		isValidating: false,
	});

	// 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() {
			// If we already have a valid authenticated session, revalidate in the background:
			// keep content stable and only set isValidating=true.
			setAuth((prev) => {
				const hasUser = prev.status === "authenticated" && prev.user;
				if (hasUser) {
					return { ...prev, error: null, isValidating: true };
				}
				return {
					status: "loading",
					user: null,
					error: null,
					isValidating: false,
				};
			});

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

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

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

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

					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;

				// If we were already authenticated, fail open:
				// keep the last known user/session and just end validating.
				setAuth((prev) => {
					const hasUser = prev.status === "authenticated" && prev.user;
					if (hasUser) {
						return { ...prev, isValidating: false };
					}

					// Initial load failed -> show error state (AuthGate handles it).
					return {
						status: "error",
						user: null,
						error:
							"Sitzung konnte nicht geprüft werden. Bitte erneut versuchen.",
						isValidating: false,
					};
				});
			}
		}

		runSessionCheck();

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

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