import { useRouter } from "next/router";
import {
	createContext,
	type FC,
	type ReactNode,
	useContext,
	useEffect,
} from "react";
import { LoadingPage } from "~/components/loading";
import type { Session, SessionStatus } from "~/server/api/trpc";
import { api } from "~/utils/api";

type ValidSession = {
	user: Session;
	status: Extract<SessionStatus, "AUTHENTICATED">;
};

type InvalidStatus = Exclude<SessionStatus, "AUTHENTICATED"> | "LOADING";
type InvalidSession = {
	status: InvalidStatus;
	user: null;
};

type SessionContextType = ValidSession | InvalidSession;

const SessionContext = createContext<SessionContextType>({
	status: "LOADING",
	user: null,
});

export const SessionProvider: FC<{ children: ReactNode }> = ({ children }) => {
	const router = useRouter();
	const utils = api.useUtils();

	const { data, isLoading } = api.auth.getSession.useQuery(undefined, {
		refetchInterval: 30000,
		//refetchOnMount: true,
		//refetchOnReconnect: true,
		refetchOnWindowFocus: true,
		staleTime: Infinity,
		retry: false,
		meta: {
			isSessionQuery: true,
		},
	});

	const session = data?.session ?? null;
	const sessionStatus = data?.sessionStatus ?? "LOADING";

	// Invalidate session on route change
	useEffect(() => {
		const handleRouteChange = () => {
			if (isLoading) return;
			utils.auth.getSession.invalidate().catch((error: Error) => {
				console.error("Error invalidating session on route change:", error);
			});
		};
		router.events.on("routeChangeComplete", handleRouteChange);
		return () => {
			router.events.off("routeChangeComplete", handleRouteChange);
		};
	}, [router, utils]);

	// Invalidate session if user is null
	// useEffect(() => {
	// 	if (!session && status === "success") {
	// 		utils.auth.getSession.invalidate().catch((error: Error) => {
	// 			console.error("Error during session invalidation:", error);
	// 		});
	// 	}
	// }, [session, status]);

	const sessionValue: SessionContextType =
		session && sessionStatus === "AUTHENTICATED"
			? {
					user: session, // TypeScript knows user is non-null here
					status: "AUTHENTICATED", // matches ValidSession
				}
			: {
					user: null, // matches InvalidSession
					status: sessionStatus as InvalidStatus, // TypeScript knows this is not "AUTHENTICATED"
				};

	return (
		<SessionContext.Provider value={sessionValue}>
			{isLoading ? <LoadingPage /> : children}
		</SessionContext.Provider>
	);
};

export const useSession = () => useContext(SessionContext);

export const EnforcedSessionContext = createContext<ValidSession | undefined>(
	undefined,
);
/**
 * AreaRiservata specific session context. It ensures that the session is valid.
 */

export const useEnforcedSession = () => {
	const session = useContext(EnforcedSessionContext);
	if (!session) {
		throw new Error(
			"useValidSession must be used within a ValidSessionProvider",
		);
	}
	return session;
};
