'use client';

import { ReactNode, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import useSWRImmutable from 'swr/immutable';

import { useAuth } from '@/services/hooks/useAuth';
import { httpClientFetcher, SWRHttpKey } from '@/services/http/client';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { BaseApiResponse, GetMeResponse } from '@/types/api/api-general';
import { AxiosError } from 'axios';

interface RequireAuthProps {
  children?: ReactNode;
}

const RequireAuth = ({ children }: RequireAuthProps) => {
  const router = useRouter();
  const { setUser, setIsLoadingUser } = useAuth();

  const {
    data: userResponse,
    isLoading: isLoadingUserResponse,
    error: userErrorResponse,
  } = useSWRImmutable<
    GetMeResponse & { ok?: boolean },
    AxiosError<BaseApiResponse>,
    SWRHttpKey
  >('/sso/userinfo', httpClientFetcher, {
    shouldRetryOnError: false,
    revalidateOnFocus: false,
    revalidateOnReconnect: false,
    refreshInterval: 0,
  });

  useEffect(() => {
    setIsLoadingUser(isLoadingUserResponse);
  }, [isLoadingUserResponse, setIsLoadingUser]);

  useEffect(() => {
    if (isResponseSuccess(userResponse)) {
      setUser(userResponse.data);
    } else if (
      isResponseError(userErrorResponse?.response?.data) &&
      typeof window !== 'undefined'
    ) {
      router.replace(
        `${process.env.NEXT_PUBLIC_SSO_LOGIN_URL as string}?redirect_url=${window.location.href}`
      );
    }
  }, [userResponse, userErrorResponse, setIsLoadingUser, setUser]);

  if (isLoadingUserResponse && !userResponse && !userErrorResponse) {
    return (
      <div className='w-full flex flex-row justify-center items-center p-4'>
        <span className='loading loading-spinner loading-xl' />
      </div>
    );
  }

  return <>{isResponseSuccess(userResponse) && children}</>;
};

export default RequireAuth;
