import axios, { AxiosInstance, InternalAxiosRequestConfig } from 'axios';

interface ServiceConfig {
  baseURL: string;
}

const createAxiosInstance = ({ baseURL }: ServiceConfig) =>
  axios.create({
    baseURL,
    headers: {
      'Content-Type': 'application/json',
    },
  });

// Base URLs
export const PROD_BASE_URL = 'https://dev-portal.spartify.io';
export const STAGING_BASE_URL = 'https://staging.dev-portal.spartify.io';
export const LOCAL_BASE_URL = 'https://localhost:44327';

// Development environment instances
const ordinoServiceAxios = createAxiosInstance({
  baseURL: PROD_BASE_URL,
});

const ordinoPartnerServiceAxios = createAxiosInstance({
  baseURL: `${PROD_BASE_URL}/partners`,
});
const ordinoTeamServiceAxios = createAxiosInstance({
  baseURL: `${PROD_BASE_URL}/teams`,
});

const ordinoUserServiceAxios = createAxiosInstance({
  baseURL: `${PROD_BASE_URL}/users`,
});

const ordinoUserApiKeyServiceAxios = createAxiosInstance({
  baseURL: `${PROD_BASE_URL}/user-api-keys`,
});

// Staging environment instances
const stagingOrdinoServiceAxios = createAxiosInstance({
  baseURL: STAGING_BASE_URL,
});

const stagingOrdinoPartnerServiceAxios = createAxiosInstance({
  baseURL: `${STAGING_BASE_URL}/partners`,
});

const stagingOrdinoTeamServiceAxios = createAxiosInstance({
  baseURL: `${STAGING_BASE_URL}/teams`,
});

const stagingOrdinoUserServiceAxios = createAxiosInstance({
  baseURL: `${STAGING_BASE_URL}/users`,
});

const stagingOrdinoUserApiKeyServiceAxios = createAxiosInstance({
  baseURL: `${STAGING_BASE_URL}/user-api-keys`,
});

//#region prod Environment
const ordinoSystemApiKeyServiceAxios = createAxiosInstance({
  baseURL: `${PROD_BASE_URL}/api/v1/system-api-key-external`,
});

const ordinoProjectServiceAxios = createAxiosInstance({
  baseURL: `${PROD_BASE_URL}/api/v1/project-external`,
});
//#endregion

//#region staging Environment
const stagingOrdinoSystemApiKeyServiceAxios = createAxiosInstance({
  baseURL: `${STAGING_BASE_URL}/api/v1/system-api-key-external`,
});

const stagingOrdinoProjectServiceAxios = createAxiosInstance({
  baseURL: `${STAGING_BASE_URL}/api/v1/project-external`,
});
//#endregion

//#region Local Environment
const localOrdinoSystemApiKeyServiceAxios = createAxiosInstance({
  baseURL: `${LOCAL_BASE_URL}/api/v1/system-api-key-external`,
});
const localOrdinoProjectServiceAxios = createAxiosInstance({
  baseURL: `${LOCAL_BASE_URL}/api/v1/project-external`,
});
//#endregion

const addAuthTokenInterceptor = (
  instance: AxiosInstance,
  authToken: string
) => {
  instance.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
      if (authToken)
        config.headers["Spartify-Key"] = authToken;
      return config;
    },
    (error) => {
      return Promise.reject(error);
    }
  );
};

const instancesRequiringAuth: AxiosInstance[] = [
  localOrdinoSystemApiKeyServiceAxios,
  localOrdinoProjectServiceAxios,
  stagingOrdinoSystemApiKeyServiceAxios,
  stagingOrdinoProjectServiceAxios,
  ordinoSystemApiKeyServiceAxios,
  ordinoProjectServiceAxios,
];

export const initializeAuthInterceptors = (authToken: string) => {
  instancesRequiringAuth.forEach((instance) => {
    addAuthTokenInterceptor(instance, authToken);
  });
};

export {
  // production instances
  ordinoPartnerServiceAxios,
  ordinoProjectServiceAxios,
  ordinoTeamServiceAxios,
  ordinoUserServiceAxios,
  ordinoSystemApiKeyServiceAxios,
  ordinoUserApiKeyServiceAxios,
  ordinoServiceAxios,

  // Staging instances
  stagingOrdinoServiceAxios,
  stagingOrdinoPartnerServiceAxios,
  stagingOrdinoProjectServiceAxios,
  stagingOrdinoTeamServiceAxios,
  stagingOrdinoUserServiceAxios,
  stagingOrdinoSystemApiKeyServiceAxios,
  stagingOrdinoUserApiKeyServiceAxios,

  //Local instances
  localOrdinoSystemApiKeyServiceAxios,
  localOrdinoProjectServiceAxios
};
