import { Container, TaskQueue } from 'aurelia-framework';
import { UISelect } from '../ui-select';
import 'select2';

var AjaxAdapter = jQuery.fn.select2.amd.require('select2/data/ajax');
var SelectAdapter = jQuery.fn.select2.amd.require('select2/data/select');

class DataAdapterUtils {
  public static select(customDataAdapterInstance, superClass, data, withTags: boolean) {
    const taskQueue = Container.instance.get(TaskQueue);
    const $options = customDataAdapterInstance.$element.find('option');
    $options.removeAttr('data-select2-id');
    try {
      customDataAdapterInstance.uiSelect.ignoreChange = true;
      if (Array.isArray(customDataAdapterInstance.uiSelect.value)) {
        // select multiple
        customDataAdapterInstance.uiSelect.value.push(data.id);

        taskQueue.queueTask(() => {
          // Avoid adding newly created tag after it has already been created using the relation-helper
          if (false === withTags || typeof data.id !== 'string') {
            superClass.prototype.select.call(customDataAdapterInstance, data);
          }
          customDataAdapterInstance.uiSelect.ignoreChange = false;
        });
      }
      else {
        // Check if we are binded to a dataformat object
        if (customDataAdapterInstance.uiSelect.value != null && Object.keys(customDataAdapterInstance.uiSelect.value).length > 0 && Object.keys(customDataAdapterInstance.uiSelect.value).indexOf('id') > -1) {
          customDataAdapterInstance.uiSelect.value = { id: data.id.toString(), text: data.text };
        }
        else {
          if (customDataAdapterInstance.uiSelect.value != data.id) {
            var numberValue = Number(data.id);
            if (!Number.isNaN(numberValue)) {
              customDataAdapterInstance.uiSelect.value = numberValue;
            }
            else {
              customDataAdapterInstance.uiSelect.value = data.id;
            }
          }
        }
        taskQueue.queueTask(() => {
          superClass.prototype.select.call(customDataAdapterInstance, data);
          customDataAdapterInstance.uiSelect.ignoreChange = false;
        });
      }
    }
    catch {
      customDataAdapterInstance.uiSelect.ignoreChange = false;
    }
  }
  public static unselect(customDataAdapterInstance, superClass, data) {
    const $options = customDataAdapterInstance.$element.find('option');
    $options.removeAttr('data-select2-id');
    if (Array.isArray(customDataAdapterInstance.uiSelect.value)) {
      // select multiple
      if (customDataAdapterInstance.uiSelect.value.some(x => x == data.id)) {
        var index: number = customDataAdapterInstance.uiSelect.value.findIndex(x => x == data.id);
        customDataAdapterInstance.uiSelect.value.splice(index, 1);
      }
    }
    else {
      // select classic
      if (customDataAdapterInstance.uiSelect.value == data.id) {
        customDataAdapterInstance.uiSelect.value = null;
      }
      else if (Object.keys(customDataAdapterInstance.uiSelect.value).length > 0 && Object.keys(customDataAdapterInstance.uiSelect.value).indexOf('id') > -1 && customDataAdapterInstance.uiSelect.value.id == data.id) {
        // we are binded to a dataformat object
        customDataAdapterInstance.uiSelect.value = null;
      }
    }
    return superClass.prototype.unselect.call(customDataAdapterInstance, data);
  }
}

export class CustomSelectAdapter extends SelectAdapter {
  private uiSelect: UISelect;

  constructor(private $element: JQuery<HTMLSelectElement>, options) {
    super($element, options);
    this.uiSelect = $element.parent().get(0).au.controller.viewModel as UISelect;
  }
  select(data) {
    DataAdapterUtils.select(this, SelectAdapter, data, this.options.options.tags);
  }

  unselect(data) {
    return DataAdapterUtils.unselect(this, SelectAdapter, data);
  }
}

export class CustomAjaxAdapter extends AjaxAdapter {
  private uiSelect: UISelect;

  constructor(private $element: JQuery<HTMLSelectElement>, options) {
    super($element, options);
    this.uiSelect = $element.parent().get(0).au.controller.viewModel as UISelect;
  }
  select(data) {
    DataAdapterUtils.select(this, AjaxAdapter, data, this.options.options.tags);
  }

  unselect(data) {
    return DataAdapterUtils.unselect(this, SelectAdapter, data);
  }

  item($option: JQuery<HTMLInputElement>) {
    if ($option.length > 0 && $option.get(0).value == "null") return { id: null };
    return super.item($option);
  }
}
