import axios from 'axios';
import _ from 'lodash';
import https from 'https';

function createSecureAxiosInstance(baseURL: string) {
  const agent = new https.Agent({
    rejectUnauthorized: false,
  });
  return axios.create({
    httpsAgent: agent,
    baseURL,
  });
}

function getBaseUrl(url: string) {
  if (process?.env?.APIM_ENV_BASE_URL) {
    return process.env.APIM_ENV_BASE_URL;
  } else {
    return url;
  }
}

export const fetchCaptureId = async (
  reqBody: any,
  headers: any,
): Promise<any> => {
  let captureData = null;
  const requestBody = JSON.parse(reqBody);
  const requestHeader = headers;
  const { apiName, orgName, catalogName, gatewayName, url } = requestBody;

  const apiUrl = getBaseUrl(url);

  const captureIdApiUrl = `${apiUrl}/api/catalogs/${orgName}/${catalogName}/configured-gateway-services/${gatewayName}/assembly-debug`;
  const token = requestHeader['authorization'];
  
  try {
    if (token) {
      const axiosInstance = createSecureAxiosInstance(apiUrl);
      const response: any = await axiosInstance.post(
        captureIdApiUrl,
        { FilterByAPI: apiName }, // <-- request body
        {
          headers: {
            Authorization: token,
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
        },
      );
      if (response?.data) {
        captureData = response?.data;
        return captureData;
      }
    }
    return captureData;
  } catch (err) {
    console.error('err ==> ', err);
    return captureData;
  }
};

const fetchTransactionId = async (
  url: string,
  token: string,
): Promise<string> => {
  const apiPath = url;
  const axiosInstance = createSecureAxiosInstance(url);
  const allTransactions: any = await axiosInstance.get(apiPath, {
    headers: {
      Authorization: token,
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
  });

  const transactionList = Array.isArray(allTransactions)
    ? allTransactions
    : [allTransactions];
  const transactionId = _.get(transactionList, '0.Probe.ProbeID');
  return transactionId;
};

const fetchCatalogData = async (req: any, headers: any): Promise<any> => {
  const token = headers['authorization'];
  const requestBody = JSON.parse(req);
  const { orgId, catalogName, apiName, apiVersion, url } = requestBody;

  const apiUrl = getBaseUrl(url);

  const apiPath = `${apiUrl}/api/catalogs/${orgId}/${catalogName}/apis/${apiName}/${apiVersion}?fields=add(catalog_api,product_urls)'`;

  let catalogData = null;

  try {
    const axiosInstance = createSecureAxiosInstance(apiUrl);
    catalogData = await axiosInstance.get(apiPath, {
      headers: {
        Authorization: token,
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
    });
    return catalogData?.data?.catalog_api;
  } catch (error) {
    console.error('catalog error ==>', error);
    return catalogData;
  }
};

/**
 * Extracts trace data values from the request body
 * @param requestBody - The request body containing trace data
 * @returns An object with extracted values
 */
const fetchTraceData = async (req: any, headers: any): Promise<any> => {
  if (!req) {
    return {};
  }

  const requestBody = JSON.parse(req);
  const requestHeader = headers;
  const token = requestHeader['authorization'];

  const { orgName, catalogName, gatewayName, transactionId, captureId, url } =
    requestBody;

  let traceData = null;
  const apiUrl = getBaseUrl(url);

  const captureIdApiUrl = `${apiUrl}/api/catalogs/${orgName}/${catalogName}/configured-gateway-services/${gatewayName}/assembly-debug`;

  try {
    let transId = '';

    if (!transactionId) {
      const transactioApiUrl = `${captureIdApiUrl}/${captureId}/transaction`;
      const transactionResponseId = await fetchTransactionId(
        transactioApiUrl,
        token,
      );
      transId = transactionResponseId;
    } else {
      transId = transactionId;
    }
    if (transId) {
      const transactioApiUrl = `${captureIdApiUrl}/${captureId}/transaction`;
      const axiosInstance = createSecureAxiosInstance(apiUrl);
      const traceResponse: any = await axiosInstance.get(
        `${transactioApiUrl}/${transId}`,
        {
          headers: {
            Authorization: token,
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
        },
      );
      traceData = traceResponse?.data;
    }
    return traceData;
  } catch (error) {
    console.error('fetch trace error', error);
    return traceData;
  }
};

export const fetchTraceAndCatalogData = async (
  reqBody: any,
  headers: any,
): Promise<any> => {
  const traceData = await fetchTraceData(reqBody, headers);
  const catalogData = await fetchCatalogData(reqBody, headers);
  return {
    traceData,
    catalogData,
  };
};
