import { useEffect, useState, useCallback } from 'react';
import { useRouter } from 'next/router';
import { useDispatch, useSelector } from 'react-redux';
import { IRootState } from '@/store';
import { setUser, setUserName, setUserEmail, setUserRole } from '@/store/userConfigSlice';

interface ProtectedRouteProps {
    children: React.ReactNode;
}

const AUTH_CACHE_TTL_MS = 5 * 60 * 1000;
let lastVerifiedAt = 0;
let verifyPromise: Promise<boolean> | null = null;

const getStoredUser = () => {
    if (typeof window === 'undefined') return null;
    return localStorage.getItem('user');
};

const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
    const router = useRouter();
    const [authState, setAuthState] = useState<'loading' | 'authenticated' | 'unauthenticated'>('loading');
    const user = useSelector((state: IRootState) => state.userConfig.user);
    const dispatch = useDispatch();

    const verifyAuth = useCallback(
        async (force = false): Promise<boolean> => {
            const storedUser = getStoredUser();
            if (!storedUser || storedUser === 'false') {
                lastVerifiedAt = 0;
                setAuthState('unauthenticated');
                return false;
            }

            if (!force && user !== 'false' && Date.now() - lastVerifiedAt < AUTH_CACHE_TTL_MS) {
                setAuthState('authenticated');
                return true;
            }

            if (!force && verifyPromise) {
                return verifyPromise;
            }

            verifyPromise = (async () => {
                try {
                    const api_url = process.env.API_URL;
                    const response = await fetch(`${api_url}api/users/admin-account`, {
                        method: 'GET',
                        headers: { 'Content-Type': 'application/json' },
                        credentials: 'include',
                    });

                    const res = await response.json();
                    if (!response.ok) {
                        dispatch(setUser('false'));
                        lastVerifiedAt = 0;
                        setAuthState('unauthenticated');
                        return false;
                    }

                    dispatch(setUserName(res.user.name));
                    dispatch(setUserEmail(res.user.email));
                    dispatch(setUserRole(res.user.role ?? ' '));
                    lastVerifiedAt = Date.now();
                    setAuthState('authenticated');
                    return true;
                } catch (error) {
                    console.error(error);
                    setAuthState('unauthenticated');
                    return false;
                } finally {
                    verifyPromise = null;
                }
            })();

            return verifyPromise;
        },
        [dispatch, user]
    );

    useEffect(() => {
        const storedUser = getStoredUser();
        if (!storedUser || storedUser === 'false') {
            lastVerifiedAt = 0;
            setAuthState('unauthenticated');
            return;
        }
        verifyAuth();
    }, [user, verifyAuth]);

    useEffect(() => {
        if (authState === 'unauthenticated') {
            router.replace('/auth/login');
        }
    }, [authState, router]);

    if (authState === 'loading') {
        return (
            <div className="flex min-h-[50vh] items-center justify-center">
                <svg width="48" height="48" viewBox="0 0 135 135" xmlns="http://www.w3.org/2000/svg" fill="currentColor" className="text-primary">
                    <path d="M67.447 58c5.523 0 10-4.477 10-10s-4.477-10-10-10-10 4.477-10 10 4.477 10 10 10zm9.448 9.447c0 5.523 4.477 10 10 10 5.522 0 10-4.477 10-10s-4.478-10-10-10c-5.523 0-10 4.477-10 10zm-9.448 9.448c-5.523 0-10 4.477-10 10 0 5.522 4.477 10 10 10s10-4.478 10-10c0-5.523-4.477-10-10-10zM58 67.447c0-5.523-4.477-10-10-10s-10 4.477-10 10 4.477 10 10 10 10-4.477 10-10z">
                        <animateTransform attributeName="transform" type="rotate" from="0 67 67" to="-360 67 67" dur="2.5s" repeatCount="indefinite" />
                    </path>
                </svg>
            </div>
        );
    }

    if (authState === 'unauthenticated') {
        return null;
    }

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

export default ProtectedRoute;
