'use client';

import { ReactNode, useEffect } from 'react';
import useSWR from 'swr';

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

interface RequireAuthProps {
  children?: ReactNode;
}

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

  const {
    data: userResponse,
    isLoading: isLoadingUserResponse,
    error: userErrorResponse,
  } = useSWR<
    GetMeResponse & { ok?: boolean },
    AxiosError<BaseApiResponse>,
    SWRHttpKey
  >('/sso/userinfo', httpClientFetcher, {
    shouldRetryOnError: false,

    // refresh every 12 minutes
    refreshInterval: 12 * 60 * 1000,
  });

  useEffect(() => {
    if (isResponseSuccess(userResponse)) {
      setUser(userResponse.data);
    }
  }, [userResponse, setUser]);

  // Explicitly handle 401 redirect from the component level
  useEffect(() => {
    if (
      isResponseError(userResponse) &&
      userErrorResponse?.response?.status === 401
    ) {
      // Clear cache to prevent stale data from rendering children
      // mutate('/sso/userinfo', undefined, { revalidate: false }); // Optional: if using global mutate
      setUser(undefined);
      redirectToSSO();
    }
  }, [userErrorResponse, setUser, userResponse]);

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

  useEffect(() => {
    const interval = setInterval(
      async () => {
        await AuthApi.refresh();
      },
      12 * 60 * 1000
    );

    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    const refreshUserSession = async () => {
      await AuthApi.refresh();
    };

    if (user) {
      refreshUserSession();
    }
  }, [user]);

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

  if (!isLoadingUserResponse && userErrorResponse) {
    return (
      <div className='w-full h-screen flex flex-col justify-center items-center gap-4'>
        <h2 className='text-2xl font-bold text-error'>Authentication Failed</h2>
        <p className='text-gray-600'>
          Please try refreshing the page or contact support if the problem
          persists.
        </p>
        <button className='btn btn-primary' onClick={() => redirectToSSO()}>
          Retry
        </button>
      </div>
    );
  }

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

export default RequireAuth;
