import each from 'lodash/each';
import filter from 'lodash/filter';
import qs from 'qs';
import { rawRequest, gql } from 'graphql';
import { sendHttpRequestInBrowser } from './browser';

const sendNetworkRequest = async (item, options) => {
  return new Promise((resolve, reject) => {
    if(item.type === 'http') {
      const timeStart = Date.now();
      sendHttpRequest(item.draft ? item.draft.request : item.request, options)
        .then((response) => {
          const timeEnd = Date.now();
          resolve({
            state: 'success',
            data: response.data,
            headers: Object.entries(response.headers),
            size: response.headers["content-length"] || 0,
            status: response.status,
            duration: timeEnd - timeStart
          });
        })
        .catch((err) => reject(err));
    }
  });
};

const sendHttpRequest = async (request, options) => {
  return new Promise((resolve, reject) => {
    const { ipcRenderer } = window;

    const headers = {};
    each(request.headers, (h) => {
      if(h.enabled) {
        headers[h.name] = h.value;
      }
    });

    let axiosRequest = {
      method: request.method,
      url: request.url,
      headers: headers
    };

    if(options && options.cancelToken) {
      axiosRequest.cancelToken = options.cancelToken;
    }

    if(request.body.mode === 'json') {
      axiosRequest.headers['content-type'] = 'application/json';
      try {
        axiosRequest.data = JSON.parse(request.body.json);
      } catch (ex) {
        axiosRequest.data = request.body.json;
      }
    }

    if(request.body.mode === 'text') {
      axiosRequest.headers['content-type'] = 'text/plain';
      axiosRequest.data = request.body.text;
    }

    if(request.body.mode === 'xml') {
      axiosRequest.headers['content-type'] = 'text/xml';
      axiosRequest.data = request.body.xml;
    }

    if(request.body.mode === 'formUrlEncoded') {
      axiosRequest.headers['content-type'] = 'application/x-www-form-urlencoded';
      const params = {};
      const enabledParams = filter(request.body.formUrlEncoded, p => p.enabled);
      each(enabledParams, (p) => params[p.name] = p.value);
      axiosRequest.data = qs.stringify(params);
    }

    if(request.body.mode === 'multipartForm') {
      const params = {};
      const enabledParams = filter(request.body.multipartForm, p => p.enabled);
      each(enabledParams, (p) => params[p.name] = p.value);
      axiosRequest.headers['content-type'] = 'multipart/form-data';
      axiosRequest.data = params;
    }

    console.log('>>> Sending Request');
    console.log(axiosRequest);

    // Todo: Choose based on platform (web/desktop)
    sendHttpRequestInBrowser(axiosRequest)
      .then(resolve)
      .catch(reject);

    // ipcRenderer
    //   .invoke('send-http', axiosRequest)
    //   .then(resolve)
    //   .catch(reject);
  });
};

const sendGraphqlRequest = async (request,) => {
  const query = gql`${request.request.body.graphql.query}`;

  const { data, errors, extensions, headers, status } = await rawRequest(request.request.url, query);

  return {
    data,
    headers,
    data,
    errors
  }
};

export {
  sendNetworkRequest
};
