import { Notify } from "../notify/Notify";
import axios from "axios";
import { useGlobalStore } from "../../../store/GlobalStore";
import pinia from "@/store";
import { ResponseErrorWrapper } from "../error/ResponseErrorWrapper";

const globalStore = useGlobalStore(pinia);

export default class Client {
  static initHttp(axios) {
    axios.defaults.baseURL = import.meta.env.VITE_APP_API_BASE_URL;
    axios.interceptors.request.use(
      async (config) => {
        config = this.prepareInterceptorsConfig(config);
        globalStore.changeLoadingStatus(true);
        return config;
      },
      (error) => {
        console.warn(error);
        globalStore.changeLoadingStatus(false);
      }
    );
    axios.interceptors.response.use(
      (response) => {
        if (response?.status >= 200 && response?.status < 300) {
          if (response?.data?.message)
            Notify.showMessage("success", response?.data?.message);
        }
        globalStore.changeLoadingStatus(false);
        return Promise.resolve(response);
      },
      async (error) => {
        try {
          globalStore.changeLoadingStatus(false);
          return new ResponseErrorWrapper(error);
        } catch (e) {
          console.warn(e);
          globalStore.changeLoadingStatus(false);
          return Promise.reject(e);
        }
      }
    );
    return axios;
  }

  static async get(url, queryParams = null) {
    // get header
    let headers = this.getHeaders();
    // check if there is any query params inserted
    let config = {
      params: queryParams !== null ? queryParams : "",
      headers: headers,
    };
    return await axios
      .get(url, config)
      .then((res) => {
        return Promise.resolve(res);
      })
      .catch(function (error) {
        // show error if failed
        Notify.showMessage("error", Notify.getMessage(error));
      });
  }

  static async post(url, data, options = {}) {
    // get header
    let headers = this.getHeaders(options);
    return await axios
      .post(url, data, { headers: headers })
      .then((res) => {
        return Promise.resolve(res);
      })
      .catch((error) => {
        // show error if failed
        Notify.showMessage("error", Notify.getMessage(error));
      });
  }

  static async patch(url, data, options = {}) {
    // get header
    let headers = this.getHeaders(options);
    return await axios
      .patch(url, data, { headers: headers })
      .then((res) => {
        return Promise.resolve(res);
      })
      .catch((error) => {
        // show error if failed
        Notify.showMessage("error", Notify.getMessage(error));
      });
  }
  static async put(url, data, options = {}) {
    // get header
    let headers = this.getHeaders(options);
    // add _method parameter
    let config = {
      params: { _method: "PUT" },
      headers: headers,
    };
    return await axios
      .post(url, data, config)
      .then((res) => {
        return Promise.resolve(res);
      })
      .catch((error) => {
        // show error if failed
        Notify.showMessage("error", Notify.getMessage(error));
      });
  }

  static async delete(url, options = {}) {
    // get header
    let headers = this.getHeaders(options);
    return await axios
      .delete(url, { headers: headers })
      .then((res) => {
        return Promise.resolve(res);
      })
      .catch((error) => {
        // show error if failed
        Notify.showMessage("error", Notify.getMessage(error));
      });
  }

  static getHeaders(options = {}) {
    let result = {
      accept: "application/json",
      "Access-Control-Allow-Origin": "*",
      lang: localStorage.getItem("locale") || "ar",
      "ngrok-skip-browser-warning": "69420",
    };
    if (options.headers) {
      for (const [key, value] of Object.entries(options.headers)) {
        result[key] = value;
      }
    }
    return result;
  }

  static prepareInterceptorsConfig(config) {
    config.params = {
      ...config.params,
    };
    return config;
  }
}
