import axios from 'axios';
import { store } from '../../redux';
import Utils from '../../utils';
import Config from '../../config/appConstants';

function getHostName(url) {
  var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+:(\d*))/i);
  let cmsHost = ['34.225.130.79:11095', 'devportal.housing.gov.om:10443', 'stgportal-1.housing.gov.om:10443']; //let cmsHost = process.env.REACT_APP_ENV_URL;

  if (match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0) {
    if (cmsHost.includes(match[2])) {
      return {
        type: "CMS",
        url: 'lcms',
        encMode: 1
      };
    } else {
      return {
        type: "BW",
        url: 'lapps',
        encMode: 1
      };
    }
  } else {
    return null;
  }
}

function logNode() {
  axios.interceptors.request.use(request => {
    loggerPayload({
      request: request
    });
    return request;
  });
  axios.interceptors.response.use(response => {
    loggerPayload({
      response: response
    });
    return response;
  }, err => {
    loggerPayload({
      response: err.response
    });
  });
}

function templateCallCheck(postData) {
  if (postData.hasOwnProperty('response')) {
    if (postData.response.config.method.toUpperCase() === 'GET') {
      // GET 
      const fileExtension = postData.response.config.url.split(/\.(?=[^\\.]+$)/);

      if (fileExtension[1] === "json") {
        // template
        return fileExtension[1];
      } else {
        return null;
      }
    } else {
      return null;
    }
  } else if (postData.hasOwnProperty('request')) {
    if (postData.request.method.toUpperCase() === 'GET') {
      // GET 
      const fileExtension = postData.request.url.split(/\.(?=[^\\.]+$)/);

      if (fileExtension[1] === "json") {
        // template
        return fileExtension[1];
      } else {
        return null;
      }
    } else {
      return null;
    }
  } else {
    return null;
  }
}

async function loggerPayload(postData) {
  let logObj = {};
  let routeObj;
  let postObj = postData.hasOwnProperty('response') ? 'response' : 'request';

  if (postData.request !== undefined) {
    routeObj = getHostName(postData[postObj].url);
  } else if (postData.response !== undefined) {
    routeObj = getHostName(postData[postObj].config.url);
  } else {
    routeObj = null;
  }

  if (routeObj !== null && (postData.response !== undefined || postData.request !== undefined)) {
    // valid url match
    // if (urlExt !== "json") {
    if (postData.request !== undefined) {
      logObj = {
        request: {
          TransactionID: postData.request.headers.TransactionID,
          reqTime: Utils.getDateAsText(),
          url: postData.request.url,
          method: postData.request.method,
          reqHeader: JSON.stringify(postData.request.headers),
          reqPayLoad: postData.request.data
        }
      };
    } else {
      logObj = {
        response: {
          TransactionID: postData.response.config.headers.TransactionID,
          status: postData.response.request.status,
          respTime: Utils.getDateAsText(),
          url: postData.response.config.url,
          respHeader: postData.response.request.status >= 400 && postData.response.request.status <= 561 ? JSON.stringify(postData.response.headers) : JSON.stringify(postData.response.headers),
          respBody: postData.response.request.responseText
        }
      };
    } // only for fileupload


    if (logObj.hasOwnProperty("request") && logObj.request.method === "post" && logObj.request.url === Config.FILE_UPLOAD) {
      // Display the key/value pairs
      let formDataObj = {};

      for (var pair of logObj.request.reqPayLoad.entries()) {
        formDataObj[pair[0]] = routeObj.encMode === 1 ? Utils.bwDecryptHeaderAuthKey(atob(pair[1])) : pair[1];
      }

      logObj.request.reqPayLoad = btoa(Utils.bwEncryptHeaderAuthKey(formDataObj));
    }

    const requestOptions = {
      method: 'POST',
      headers: {
        'Accept': '*/*',
        'Content-Type': "application/json"
      },
      body: JSON.stringify({
        data: Utils.encryptRequestBody(logObj),
        md: routeObj.encMode
      }),
      mode: "cors"
    };
    let systemLog; // let [host, subStr] = postData.response.config.url.split(':');
    // let port = subStr.substring(6);

    if (templateCallCheck(postData) === null) {
      if (postData.hasOwnProperty(postObj)) {
        systemLog = routeObj !== null ? routeObj.url : 'lapps-remove'; //const systemLog = isCms ? 'lcms' : 'lapps'

        let endPointURL = "http://localhost:20205/" + systemLog;
        await fetch(endPointURL, requestOptions);
      }
    }
  }
}

const loginHeader = {
  'accept': 'application/json',
  'content-type': 'application/json',
  'Access-Control-Allow-Origin': '*',
  //'RequestID': (new Date().valueOf()),
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  'ApplicantType': 'USER',
  "TransactionID": ""
};
const FreezeUnFreezeHeader = {
  'accept': 'application/json',
  'content-type': 'application/json',
  //'RequestID': (new Date().valueOf()),
  'SessionID': '',
  'Region': 'MCT',
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  "AdditionalParams": "",
  "TransactionID": ""
};
const courtfreezeUnFreezeHeader = {
  'accept': 'application/json',
  'content-type': 'application/json',
  'RequestID': "",
  'SessionID': '',
  'Region': 'MCT',
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  "AdditionalParams": "",
  "TransactionID": ""
};
const afterLoginHeader = {
  'accept': 'application/json',
  'content-type': 'application/json',
  'Access-Control-Allow-Origin': '*',
  //'RequestID': (new Date().valueOf()),
  'SessionID': '',
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  'ApplicantType': 'USER',
  "TransactionID": ""
};
const afterLoginHeaderCreateUpdate = {
  'accept': 'application/json',
  'content-type': 'application/json',
  'Access-Control-Allow-Origin': '*',
  //'RequestID': (new Date().valueOf()),
  'SessionID': '',
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  'ApplicantType': 'USER',
  "TransactionID": ""
};
const fileUploadHeader = {
  'accept': 'application/json',
  'content-type': 'multipart/form-data',
  //'RequestID': (new Date().valueOf()),
  'SessionID': '',
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  'ApplicantType': 'USER',
  "TransactionID": ""
};
const paymentHeader = {
  'accept': 'application/json',
  'content-type': 'application/json',
  //'RequestID': (new Date().valueOf()),
  'SessionID': '',
  'Region': 'MCT',
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  'ApplicantType': 'USER',
  "TransactionID": ""
};
const afterLoginHeaderCommercial = {
  'accept': 'application/json',
  'content-type': 'application/json',
  'Access-Control-Allow-Origin': '*',
  //'RequestID': (new Date().valueOf()),
  'SessionID': '',
  'ApplicationID': 'WEB',
  'ChannelID': 'WEB',
  'CountryCode': 'OM',
  'Name': 'OMAN',
  'ApplicantType': 'USER',
  "TransactionID": ""
}; // axios body

function axiosResponseBody(type, url, customHeader, postData, params) {
  let fileExt = "";
  let config, queryString;
  let hostObj = getHostName(url); // let modeObj  = getHostName()

  if (type === 'GET') {
    // GET 
    let urlObj = url.split(/\.(?=[^\\.]+$)/);
    let urlExt = urlObj[1];

    if (urlExt !== "json") {
      if (params !== "" || params !== {}) {
        if (typeof params === "object") {
          queryString = Object.keys(params).map(key => key + '=' + params[key]).join('&').replace(/\s/g, '%20');
        } else {
          queryString = params.replace(/\s/g, '%20');
        }
      }
    } else {
      queryString = "";
      fileExt = urlExt;
    }

    if (urlExt !== "json" && (queryString !== '' || queryString !== {})) {
      let qString;

      if (hostObj !== null && hostObj.encMode === 1) {
        qString = "?param=" + btoa(Utils.bwEncryptHeaderAuthKey(queryString));
      } else {
        qString = "?" + queryString;
      }

      config = {
        method: type,
        url: url + qString,
        headers: customHeader
      };
    } else {
      config = {
        method: type,
        url: url,
        headers: customHeader
      };
    }
  } else {
    // POST, PUT
    let postQueryEncrypt = '',
        queryString = "";

    if (params !== "" || params !== {} || params !== undefined) {
      if (typeof params === "object" && params !== {}) {
        if (Object.keys(params).length) {
          queryString = Object.keys(params).map(key => key + '=' + params[key]).join('&').replace(/\s/g, '%20');
        }
      } else if (typeof params === "string" && params.length > 1) {
        queryString = params.replace(/\s/g, '%20'); //queryString =  params;
      }

      if (queryString !== "") {
        postQueryEncrypt = hostObj.encMode === 1 ? "?param=" + btoa(Utils.bwEncryptHeaderAuthKey(queryString)) : "?" + queryString;
      }
    }

    config = {
      method: type,
      url: postQueryEncrypt === '' ? url : url + postQueryEncrypt,
      data: hostObj.encMode === 1 ? btoa(Utils.bwEncryptHeaderAuthKey(postData)) : postData,
      headers: customHeader
    };
  }

  return new Promise((resolve, reject) => {
    axios.request(config).then(response => {
      if (type === "GET" && fileExt === "json") {
        resolve({
          data: response.data
        });
      } else {
        const decrypted = hostObj.encMode === 1 ? JSON.parse(Utils.bwDecryptHeaderAuthKey(atob(response.data))) : response.data;
        resolve({
          data: decrypted
        });
      }
    }).catch(err => {
      resolve({
        data: false
      });
      reject(err);
    });
  });
}

logNode();
export function createRequest(type, url, headerType, postData = '', params = '') {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.Authorization = `Basic ${Utils.encryptHeaderAuthKey(loginData.SessionID)}`;
    } else {
      loginData = store.getState().pki_details;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.Authorization = `Basic ${Utils.encryptHeaderAuthKey(loginData.SessionID)}`;
    }

    afterLoginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = afterLoginHeader;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function createRequestFileUpload(type, url, headerType, postData, encMode = 0) {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      fileUploadHeader.SessionID = loginData.SessionID; // fileUploadHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    } else {
      loginData = store.getState().pki_details;
      fileUploadHeader.SessionID = loginData.SessionID; //fileUploadHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    }

    fileUploadHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = fileUploadHeader;
  }

  let config = {
    method: type,
    url: url,
    data: postData,
    headers: customHeader
  };
  return new Promise((resolve, reject) => {
    axios.request(config).then(response => {
      const decrypted = encMode === 1 ? JSON.parse(Utils.bwDecryptHeaderAuthKey(atob(response.data))) : response.data;
      resolve({
        data: decrypted
      });
    }).catch(err => {
      console.log('err', type, err);
    });
  });
}
export function createRequestPayment(type, url, headerType, postData = '', params = '') {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      paymentHeader.SessionID = loginData.SessionID; //paymentHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    } else {
      loginData = store.getState().pki_details;
      paymentHeader.SessionID = loginData.SessionID; //paymentHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    }

    paymentHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = paymentHeader;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function paymentGatewayRESTCall(type, url, headerType, params, sessionID, postData = '') {
  var customHeader = '';

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    paymentHeader.SessionID = sessionID;
    paymentHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed(); //paymentHeader.AuthToken = Utils.encryptHeaderAuthKey(sessionID);

    customHeader = paymentHeader;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function createRequestCourtFreezeUnFreeze(type, url, headerType, postData = '', params = '', InvolvedPartyID) {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      courtfreezeUnFreezeHeader.SessionID = loginData.SessionID;
    } else {
      loginData = store.getState().pki_details;
      courtfreezeUnFreezeHeader.SessionID = loginData.SessionID;
    }

    courtfreezeUnFreezeHeader.RequestID = new Date().valueOf();
    courtfreezeUnFreezeHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    courtfreezeUnFreezeHeader.AdditionalParams = 'concernedpartyid:' + InvolvedPartyID;
    customHeader = courtfreezeUnFreezeHeader;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function createRequestFreezeUnFreeze(type, url, headerType, postData = '', params = '', InvolvedPartyID) {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      FreezeUnFreezeHeader.SessionID = loginData.SessionID; //afterLoginHeader.Authorization = `Basic ${Utils.encryptHeaderAuthKey(loginData.SessionID)}`;
    } else {
      loginData = store.getState().pki_details;
      FreezeUnFreezeHeader.SessionID = loginData.SessionID; //afterLoginHeader.Authorization = `Basic ${Utils.encryptHeaderAuthKey(loginData.SessionID)}`;
    }

    FreezeUnFreezeHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    FreezeUnFreezeHeader.AdditionalParams = 'concernedpartyid:' + InvolvedPartyID;
    customHeader = FreezeUnFreezeHeader;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function mohUserCreateRequest(type, url, headerType, postData = '', params) {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    } else {
      loginData = store.getState().pki_details;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    }

    afterLoginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = afterLoginHeader;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function applicantCreateUpdateRequest(type, url, headerType, postData = '', params) {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    var resourceDetails = store.getState().resourceDetails;

    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      afterLoginHeaderCreateUpdate.SessionID = loginData.SessionID; //afterLoginHeaderCreateUpdate.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    } else {
      loginData = store.getState().pki_details;
      afterLoginHeaderCreateUpdate.SessionID = loginData.SessionID; //afterLoginHeaderCreateUpdate.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    }

    if (Object.keys(resourceDetails).length) {
      // afterLoginHeaderCreateUpdate.ActionUserName = resourceDetails.InvolvedPartyID;
      // let InvolvedPartyName =  (store.getState()?.lang?.lang && store.getState()?.lang?.lang === Config.LANG.AR) ? resourceDetails?.InvolvedPartyNameArabic : resourceDetails?.InvolvedPartyName; 
      afterLoginHeaderCreateUpdate.ActionUserName = resourceDetails?.InvolvedPartyName;
      afterLoginHeaderCreateUpdate.ActionUserGUID = resourceDetails.guid;
      afterLoginHeaderCreateUpdate.ActionUserPosition = resourceDetails.Positions[0].name;
      afterLoginHeaderCreateUpdate.ActionUserDepartment = resourceDetails.Positions[0].hierarchy;
    }

    afterLoginHeaderCreateUpdate.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = afterLoginHeaderCreateUpdate;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function applicantCreateRequest(type, url, headerType, postData = '', params) {
  var customHeader = ''; // let config;

  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    } else {
      loginData = store.getState().pki_details;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    }

    afterLoginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = afterLoginHeader;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}
export function createConcurrentRequest(type, url, headerType = `1`, postData = '', params) {
  var defaultHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    defaultHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    } else {
      loginData = store.getState().pki_details;
      afterLoginHeader.SessionID = loginData.SessionID; //afterLoginHeader.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    }

    afterLoginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    defaultHeader = afterLoginHeader;
  }

  return axiosResponseBody(type, url, defaultHeader, postData, params);
}
export function applicantCommercialRequest(type, url, headerType, postData = '', params) {
  var customHeader = '';
  let loginData;

  if (headerType === 0) {
    loginHeader.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = loginHeader;
  } else {
    if (store.getState().pki_details.hasOwnProperty("OrgUserValidator")) {
      loginData = store.getState().pki_details.OrgUserValidator;
      afterLoginHeaderCommercial.SessionID = loginData.SessionID; //afterLoginHeaderCommercial.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    } else {
      loginData = store.getState().pki_details;
      afterLoginHeaderCommercial.SessionID = loginData.SessionID; //afterLoginHeaderCommercial.AuthToken = Utils.encryptHeaderAuthKey(loginData.SessionID);
    }

    afterLoginHeaderCommercial.TransactionID = Date.now() + (Math.random() * 1000).toFixed();
    customHeader = afterLoginHeaderCommercial;
  }

  return axiosResponseBody(type, url, customHeader, postData, params);
}