import axios from "axios";
import { useCallback, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { ConfigInterface, UseFortressHttpInterface, UseFortressHttpPropsInterface } from "../types/type";
import { setConfig } from "../redux/FortressConfigReducer";

/**
 * Custom hook that provides functions for making HTTP requests using Axios.
 *
 * @return {UseFortressHttpInterface} An object containing functions for making HTTP requests:
 *   - httpPost: Asynchronous function that sends a POST request to the specified URL with the provided data.
 *   - httpGet: Asynchronous function that sends a GET request to the specified URL.
 *   - httpPut: Asynchronous function that sends a PUT request to the specified URL with the provided data.
 *   - httpDelete: Asynchronous function that sends a DELETE request to the specified URL.
 *   - httpSubmitForm: Asynchronous function that sends a POST request to the specified URL with the provided data,
 *     and handles CSRF token retrieval and session storage.
 */
export function useFortressHttp(): UseFortressHttpInterface {

   const dispatch = useDispatch();
   // Get the config from redux state
   const { config } = useSelector((state: any) => state.fortressConfig as ConfigInterface);

   useMemo(() => {
      // If request config is not set, use the default config
      if (!config?.http_request_config || config?.http_request_config === undefined) {

         const storage = JSON.parse(localStorage.getItem(config.session_storage_name!)!);
         const rConfig = { headers: { Accept: "application/json", Authorization: `Bearer ${storage?.token}` } };
         dispatch(setConfig({ http_request_config: rConfig }));
      }
   }, [config?.http_request_config, config.session_storage_name, dispatch]);

   const httpPost = useCallback(
      async (url: string, data: object) => {

         try {
            const postRequest = await axios.post(config.base_api_route_url + url, data, config?.http_request_config);
            return postRequest.data;
         } catch (error) {
            console.log(error);
         }
      },
      [config.base_api_route_url, config?.http_request_config]
   );

   const httpGet = useCallback(
      async (url: string) => {
         try {
            const getRequest = await axios.get(config.base_api_route_url + url, config?.http_request_config);
            return getRequest.data;
         } catch (error) {
            console.log(error);
         }
      },
      [config.base_api_route_url, config?.http_request_config]
   );

   const httpPut = useCallback(
      async (url: string, data: object) => {

         try {
            const putRequest = await axios.put(config.base_api_route_url + url, data, config?.http_request_config);

            return putRequest.data;
         } catch (error) {
            console.log(error);
         }
      },
      [config.base_api_route_url, config?.http_request_config]
   );

   const httpDelete = useCallback(
      async (url: string) => {

         try {
            const deleteRequest = await axios.delete(config.base_api_route_url + url, config?.http_request_config);
            return deleteRequest.data;
         } catch (error) {
            console.log(error);
         }
      },
      [config.base_api_route_url, config?.http_request_config]
   );

   const httpSubmitForm : UseFortressHttpPropsInterface = useCallback(
      async (route_url, data ) => {
        axios.defaults.withCredentials = false;
        try {

         // initiate csrf cookie
          await axios.get(config.base_api_route_url + config.csrf_cookies_route_url!);
          
          const postRequest = await axios.post(config.base_api_route_url + route_url, data); // get user
          
          if(postRequest.status === 200) {
            window.localStorage.setItem(config.session_storage_name!, JSON.stringify(postRequest.data));
            window.location.href = config.after_login_path!;
          }
        } catch (error) {
          console.log(error);
        }
      },
      [config.after_login_path, config.base_api_route_url, config.csrf_cookies_route_url, config.session_storage_name]
    ) ;

   return {httpPost, httpGet, httpPut, httpDelete, httpSubmitForm};
}
