import { createFetchUniq, setFetchUniq } from '@win2win/shared-ui';
import axios, { AxiosInstance } from 'axios';
import { Dialog } from 'quasar';
import { getDynamicEnv } from '../helpers/getEnv';

const dynamicEnv = await getDynamicEnv();
let api: AxiosInstance;
let showingSessionDialog = false;

export default async ({ store, router }) => {
  let baseUrl: string;
  if (process.env.DEFAULT_SYSTEM) {
    baseUrl = process.env.API_URL ?? '';
  } else {
    baseUrl = !!Number(process.env.USE_REMOTE_API) || process.env.PROD ? dynamicEnv.API_URL ?? '' : process.env.API_URL;
  }

  api = axios.create({
    baseURL: baseUrl + (baseUrl.endsWith('/') ? '' : '/'),
    timeout: 60000,
  });

  api.interceptors.request.use(function (config) {
    if (config.url?.startsWith('/undefined')) {
      return Promise.reject(new Error('API request to undefined URL'));
    }
    const token = store.getters['auth/token'];
    config.headers.authorization = token;
    config.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate';
    config.headers.Pragma = 'no-cache';
    config.headers.Expires = '0';
    return config;
  });

  function forceSignOut() {
    window.sessionStorage.removeItem('vuex');
    showingSessionDialog = false;
    store.commit('auth/clearToken');
    router.push('/login');
  }

  api.interceptors.response.use(
    (response) => {
      const token = response.headers.authorization;
      if (token) {
        store.commit('auth/refreshToken', token);
      }
      return response;
    },
    (err) => {
      if (err.code === 'ERR_CANCELED') {
        return;
      }
      if (!showingSessionDialog && err?.response?.status === 401) {
        showingSessionDialog = true;

        const currentPath = window.location.pathname;
        if (currentPath === '/login' || !store.state.auth.token) return;
        Dialog.create({
          title: 'Sesión expirada',
          message: 'Presione "OK" para salir de la aplicación e iniciar una nueva sesión.',
        })
          .onOk(() => forceSignOut())
          .onCancel(() => forceSignOut())
          .onDismiss(() => forceSignOut());
      } else {
        throw err;
      }
    }
  );

  const fetchUniq = createFetchUniq(api);
  setFetchUniq(fetchUniq);
};

let error_msg = function (err, custom_msg: string | null = null) {
  return err?.response?.data?.message || custom_msg || 'Ocurrió un error inesperado durante el proceso.';
};

const createCancelToken = () => axios.CancelToken.source();
const isCancel = axios.isCancel;

export { api, createCancelToken, error_msg, isCancel };
