import axios from 'axios';
import debounce from 'lodash/debounce';
import isFunction from 'lodash/isFunction';

import { Request } from 'karmadata';


export default class RequestHelper {
  constructor({ type, source, onDone, onFail, filters, relatedEntities, beforeSend, delay = 350 }) {
    this.type = type;
    this.source = source;
    this.onDone = onDone;
    this.onFail = onFail;
    this.beforeSend = beforeSend;
    this.getData = debounce(this.delayedGetData, delay);
    this.filters = filters || [];
    this.relatedEntities = relatedEntities;
  }

  async fetchFromKD(value) {
    const request = Request('Search', this.source.model.getEntityType());
    const { bearerToken } = this.source.api;
    const resolvedBearer = isFunction(bearerToken) ? await bearerToken() : bearerToken;
    request.setUrlBase(this.source.api.url);
    request.setApiKey(this.source.api.key);
    request.setAuthToken(resolvedBearer);
    request.setAjaxBeforeSend(this.beforeSend);
    request.setAjaxDone(this.onDone);
    request.setAjaxFail(this.onFail);
    request.setPageRows(this.source.api.pageRows || 10);
    request.setQ(value);

    this.filters.forEach((filter) => {
      request.addFilterItem(filter);
    });

    if (this.relatedEntities) {
      request.setRelatedEntities(this.relatedEntities);
    }
    request.requestData();
  }

  fetchFromUrl() {
    axios.get(this.source.url)
      .then(response => (
        this.onDone(response)
      ))
      .catch(error => (
        this.onFail(error)
      ));
  }

  delayedGetData(value = null) {
    switch (this.type) {
      case 'url':
        this.fetchFromUrl(value);
        break;
      case 'data':
        this.onDone(
          this.source.filter(
            ({ label }) =>
              (label.match(new RegExp(value, 'gi')) !== null),
          ),
        );
        break;
      case 'request':
        this.fetchFromKD(value);
        break;
      default:
        break;
    }
  }
}
