import { useEffect, useState } from 'react';

import { RestErrorResponse } from '@/back-api';
import { toaster, toasterAPIError } from '@/components/ui/toaster';
import { useSessionService } from '@/service/session';

export type useQueryProps<TYPE> = {
  queryFunction: () => Promise<TYPE>;
  onSuccess?: (data: TYPE) => Promise<TYPE>;
  onFail?: (error: RestErrorResponse) => void;
};
export const useQuery = <TYPE>({
  queryFunction,
  onSuccess,
  onFail,
}: useQueryProps<TYPE>) => {
  const { clearToken } = useSessionService();
  const [data, setData] = useState<TYPE | undefined>(undefined);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [error, setError] = useState<RestErrorResponse | undefined>(undefined);
  useEffect(() => {
    queryFunction()
      .then((received) => {
        setData(received);
        setIsLoading(false);
        if (onSuccess) {
          onSuccess(received);
        }
      })
      .catch((error) => {
        setError(error);
        setIsLoading(false);
        if (onFail) {
          onFail(error);
        }
        toasterAPIError(error);
        if (error.status == 401) {
          // Authentication error ==> auto_disconnect
          clearToken();
          toaster.create({
            title: 'Disconnected by server',
            description: 'Token is no more available',
          });
        }
      });
  }, [setError, setIsLoading, setData, toasterAPIError, clearToken, toaster]);
  return { data, isLoading, error };
};
export type useQueryCallProps<RETURN_TYPE, PARAMETER_TYPE> = {
  queryFunction: (params: PARAMETER_TYPE) => Promise<RETURN_TYPE>;
  onSuccess?: (data: RETURN_TYPE) => void;
  onFail?: (error: RestErrorResponse) => void;
};
export const useQueryCall = <RETURN_TYPE, PARAMETERS>({
  queryFunction,
  onSuccess,
  onFail,
}: useQueryCallProps<RETURN_TYPE, PARAMETERS>) => {
  const { clearToken } = useSessionService();
  const [isCalling, setIsCalling] = useState<boolean>(true);
  const [error, setError] = useState<RestErrorResponse | undefined>(undefined);
  const call = (params: PARAMETERS) => {
    queryFunction(params)
      .then((received) => {
        setIsCalling(false);
        if (onSuccess) {
          onSuccess(received);
        }
      })
      .catch((error) => {
        setIsCalling(false);
        if (onFail) {
          onFail(error);
        }
        toasterAPIError(error);
        setError(error);
        if (error.status == 401) {
          // Authentication error ==> auto_disconnect
          clearToken();
          toaster.create({
            title: 'Disconnected by server',
            description: 'Token is no more available',
          });
        }
      });
  };
  return { call, isCalling, error };
};
