import axios from 'axios';
import debounce from 'lodash.debounce';
import moment from 'moment';

import {
  KD_COUNTRY,
  KD_STATE,
  KD_CITY,
  DATE_FORMAT_SIMPLE,
  DATE_FORMAT_WITH_HOUR,
} from '../constants';


export function dispatchCustomEvent(elem, eventName, data) {
  const event = new CustomEvent(eventName, { detail: data });
  document.dispatchEvent(event);
}

export function removeLabel(arr, labelToRemove) {
  arr.splice(
    arr.findIndex(
      elem => (
        elem.label === labelToRemove
      )), 1);
  return arr;
}

export function getChickletCategory(entityType) {
  switch (entityType) {
    case KD_COUNTRY:
      return 'orange-darker';
    case KD_STATE:
      return 'orange';
    case KD_CITY:
      return 'orange-lighter';
    default:
      return 'default';
  }
}

export class requestHelper {

  constructor({ type, source, onDone, onFail, filters }) {
    this.type = type;
    this.source = source;
    this.onDone = onDone;
    this.onFail = onFail;
    this.getData = debounce(this.delayedGetData, 800);
    this.filters = filters || [];
  }

  fetchFromKD(value) {
    const request = kd.Request(this.source.model.getEntityType(), 'Search');
    request.setUrlBase(this.source.api.url);
    request.setApiKey(this.source.api.key);
    request.setAjaxDone(this.onDone);
    request.setAjaxFail(this.onFail);
    request.setQ(value);

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

  fetchFromUrl() {
    axios.get(this.source.url)
      .then(function (response) {
        this.onDone(response);
      })
      .catch(function (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;
    }
  }
}

export function operatorSelector(dataType) {
  switch (dataType) {
    case 'String':
      return 'Eq';
      break;
    case 'Location':
      throw 'Not implemented';
      break;
    case 'Geography':
      throw 'Not implemented';
      break;
    default:
      return 'Eq';
      break;
  }
}

export function itemHandlerCreator(dataType) {
  switch (dataType) {
    case 'String':
      return ({ value, operator }) => {
        if (value.length) {
          value = value.replace(/%/g, '').trim();
        }
        if (operator === 'Like') {
          return `%${value}%`;
        }
        return value;
      };
      break;
    case 'Location':
      throw 'Not implemented';
      break;
    case 'Geography':
      throw 'Not implemented';
      break;
    case 'Boolean':
      return ({ value }) => ( String(value) === 'true' );
      break;
    case 'Number':
      return (
        ({ value }) => {
          if (Array.isArray(value)) {
            return value.map(Number);
          }
          return Number(value);
        }
      );
      break;
    case 'Date':
      return (
        ({ value }) => {
          if (Array.isArray(value)) {
            return value.map(val => new Date(val));
          }
          return new Date(value);
        }
      );
      break;
    case 'Moment':
      return (
        ({ value }) => {
          if (Array.isArray(value)) {
            return value.map(val => moment(val, DATE_FORMAT_WITH_HOUR));
          }
          return moment(value, DATE_FORMAT_WITH_HOUR);
        }
      );
      break;
    default:
      if (dataType.substring(0, 2) === 'Kd') {
        return (
          ({ value, label, entityType }) => (
            {
              KdId: value,
              KdLabel: label,
              KdEntityType: entityType,
            }
          )
        );
      }
      break;
  }
};
