import { useQueryErrorResetBoundary } from '@tanstack/react-query';
import { PropsWithChildren } from 'react';
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
import { useLocation } from 'react-router-dom';
import { APIError } from '@/widgets/fallbacks/api-error';
import { KickOutError } from '@/widgets/fallbacks/kick-out-error';
import { checkIsAxiosError, checkIsKickOutError } from '@/shared/lib/error';

/**
 * 케이스별로 Fallback 컴포넌트를 반환하는 컴포넌트 (api에러가 아니면 상위 에러 바운더리로 위임)
 * - kickout
 * - force update
 * - maintenance
 * - network
 * - common
 */
function FallbackComponent({ 
  error, 
  resetErrorBoundary 
}: FallbackProps) {
  // api 에러가 아닌 경우 상위 에러 바운더리로 위임
  if(!checkIsAxiosError(error)){
    throw error;
  } 

  if(checkIsKickOutError(error)){
    return (
      <KickOutError error={ error } />
    );
  } 
  return (
    <APIError 
      error={ error } 
      resetErrorBoundary={ resetErrorBoundary } 
    />
  );
}

type Props = PropsWithChildren;

export const GlobalAPIErrorBoundary = ({ children }: Props) => {
  const { reset } = useQueryErrorResetBoundary();
  const { key } = useLocation();
  return (
    <ErrorBoundary 
      onReset={ reset } 
      resetKeys={ [key] } 
      FallbackComponent={ FallbackComponent }
    >{ children }</ErrorBoundary>
  );
};
