import { Text } from '@radix-ui/themes';
import { AxiosError } from 'axios';
import { useLocation, useNavigate } from 'react-router';
import { toast } from 'react-toastify';

export enum ResponseErrorToastId {
  NetworkError = 'network-error',
}

export type DefaultResponseErrorHandlerOptions = {
  disableUnauthorizedHandling?: boolean;
  disableHandleUnexpectedErrors?: boolean;
  disableIgnoreCanceledRequests?: boolean;
};

/**
 *
 * @param err error value
 * @returns {boolean} true if the error was handled, false otherwise
 */
const defaultResponseErrorHandler =
  (navigate: ReturnType<typeof useNavigate>, location: ReturnType<typeof useLocation>) =>
  (err: unknown, options?: DefaultResponseErrorHandlerOptions): boolean => {
    if (!(err instanceof AxiosError) && !options?.disableHandleUnexpectedErrors) {
      toast.error(
        <div>
          <Text weight="bold">Unexpected Error:</Text>
          <br /> An unexpected error occurred. Please try again later.
        </div>,
        {
          position: 'top-center',
          autoClose: false,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: false,
          progress: undefined,
          theme: 'colored',
        }
      );
      return true;
    }

    if (!(err instanceof AxiosError)) return false;

    if (err.message === 'canceled') {
      // request was aborted, ignore but return true to indicate it was handled
      return !options?.disableIgnoreCanceledRequests;
    }

    if (err.message === 'Network Error') {
      toast.error(
        <div>
          <Text weight="bold">Network Error:</Text>
          <br /> Unable to reach the server. Please check your internet connection and try again.
        </div>,
        {
          toastId: ResponseErrorToastId.NetworkError,
          position: 'top-center',
          autoClose: false,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: false,
          progress: undefined,
          theme: 'colored',
        }
      );
      return true;
    }

    // handle 401 Unauthorized globally
    if (err.status === 401 && !options?.disableUnauthorizedHandling) {
      // store current path for redirect after login
      const currentPath = location.pathname + location.search;
      const searchParam = new URLSearchParams();
      searchParam.set('redirect', currentPath);
      searchParam.set('message', 'Session expired, please log in again');
      navigate(`/login?${searchParam.toString()}`);
      return true;
    }

    if (err.status === 403) {
      toast.error(
        <div>
          <Text weight="bold">Forbidden:</Text>
          <br /> You do not have permission to perform this action.
        </div>,
        {
          position: 'top-center',
          autoClose: 5000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: false,
          progress: undefined,
          theme: 'colored',
        }
      );
      return true;
    }

    return false;
  };

export function useResponseErrorHandler() {
  const navigate = useNavigate();
  const location = useLocation();
  return { defaultResponseErrorHandler: defaultResponseErrorHandler(navigate, location) };
}
