'use client';

import { store, AppDispatch } from '@/store/app';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { Toaster } from 'sonner';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { fetchAuthData, isLoadingSelector } from '@/store/authSlice';
import Preloader from '@/components/landing/Preloader';
import { publicApi } from '@/store/slice/publicApi';

const queryClient = new QueryClient();

// Inner wrapper to handle first load, session fetch, and public API prefetch
const InnerWrapper = ({ children }: { children: React.ReactNode }) => {
	const dispatch = useDispatch<AppDispatch>(); // typed dispatch
	const isAuthLoading = useSelector(isLoadingSelector);
	const [firstLoad, setFirstLoad] = useState(true);

	useEffect(() => {
		// First-load preloader for 2 seconds
		const timer = setTimeout(() => setFirstLoad(false), 2000);

		// Fetch session info
		dispatch(fetchAuthData());

		// Prefetch public API queries only if cache is empty
		const state = store.getState();

		const publicQueries: Array<keyof typeof publicApi.endpoints> = [
			'getPublicContact',
			'getPublicGalary',
			'getPublicService',
			'getPublicVehecle',
			'getPublicTrustedClients',
		];

		publicQueries.forEach((endpoint) => {
			const cachedData = state.api.queries[`publicApi/${endpoint}()`];
			if (!cachedData || !cachedData?.data) {
				// Trigger RTK query prefetch
				dispatch(
					// @ts-ignore: dispatch accepts any endpoint prefetch
					publicApi.endpoints[endpoint].initiate(undefined, {
						forceRefetch: true,
					})
				);
			}
		});

		return () => clearTimeout(timer);
	}, [dispatch]);

	// Show preloader if first load OR session is loading
	if (firstLoad || isAuthLoading) return <Preloader fullScreen />;

	return <>{children}</>;
};

const ClientWrapper = ({ children }: { children: React.ReactNode }) => {
	return (
		<QueryClientProvider client={queryClient}>
			<Provider store={store}>
				<Toaster position="top-right" />
				<InnerWrapper>{children}</InnerWrapper>
			</Provider>
		</QueryClientProvider>
	);
};

export default ClientWrapper;
