import axios, { AxiosInstance, AxiosError } from 'axios';
import { boot } from 'quasar/wrappers';
import config from '../config';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { LocalStorage } from 'quasar';
import {Notify} from 'quasar';
import {Router} from 'src/router';

declare module 'vue/types/vue' {
  interface Vue {
    $axios: AxiosInstance;
  }
}

export const setBaseUrl = (url: string) => {
  LocalStorage.set('baseURL', url);
  axios.defaults.baseURL = url;
  Notify.create({
    message: "Serveraddresse gespeichert",
    position: "bottom",
    caption: `${url}`,
    color: "positive"
  })
  setTimeout(() => {window.location.reload()}, 5000)

}

export default boot<Store<StateInterface>>(({ Vue, store, router }) => {
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
  Vue.prototype.$axios = axios;
  const baseURL = <string | undefined>LocalStorage.getItem('baseURL');
  if (baseURL){
    axios.defaults.baseURL = baseURL
  } else {
    axios.defaults.baseURL = config.baseURL;
  }
  /***
   * Intercept requests and insert Token if available
   */
  axios.interceptors.request.use(config => {
    const session = store.state.session.currentSession;
    if (session?.token) {
      config.headers = { Authorization: 'Bearer ' + session.token };
    }
    return config;
  });

  /***
   * Intercept responses
   *   - filter 401 --> logout
   *   - filter timeout or 502-504 --> backendOffline
   */
  axios.interceptors.response.use(
    response => response,
    error => {
      if (error) {
        const e = <AxiosError>error;
        if (
          e.code === 'ECONNABORTED' ||
          (e.response && e.response.status >= 502 && e.response.status <= 504)
        ) {
          return router.push({
            name: 'offline',
            query: { redirect: router.currentRoute.fullPath }
          });
        } else if (e.response && e.response.status == 401) {
          if (router.currentRoute.name !== 'login') return store.dispatch('session/clearCurrent');
        }
      }
      return Promise.reject(error);
    }
  );
});

export { axios };