import { __assign } from 'tslib';
import { KeyCodes, isIE11 } from '@uifabric-vue/utilities';
import Vue from 'vue';

var SELECTION_FORWARD = "forward";
var SELECTION_BACKWARD = "backward";
var Autofill = Vue.extend({
  name: "Autofill",
  props: {
    defaultVisibleValue: { type: String, default: "" },
    suggestedDisplayValue: { type: String, default: "" },
    preventValueSelection: { type: Boolean, default: false },
    enableAutofillOnKeyPress: { type: Array, default: function() {
      return [KeyCodes.down, KeyCodes.up];
    } },
    value: { type: String, default: void 0 },
    disabled: { type: Boolean, default: false }
  },
  data: function() {
    return {
      inputValue: this.defaultVisibleValue || "",
      autoFillEnabled: true,
      isComposing: false,
      timeout: -1
    };
  },
  computed: {
    cursorLocation: function() {
      if (this.$refs.input) {
        var inputElement = this.$refs.input;
        if (inputElement.selectionDirection !== SELECTION_FORWARD) {
          return inputElement.selectionEnd;
        } else {
          return inputElement.selectionStart;
        }
      } else {
        return -1;
      }
    },
    cursor: function() {
      var _a, _b;
      var inputElement = this.$refs.input;
      if (inputElement && inputElement.selectionStart !== this.internalValue.length) {
        return {
          start: (_a = inputElement.selectionStart) !== null && _a !== void 0 ? _a : inputElement.value.length,
          end: (_b = inputElement.selectionEnd) !== null && _b !== void 0 ? _b : inputElement.value.length,
          dir: inputElement.selectionDirection || "backward"
        };
      }
      return null;
    },
    isValueSelected: function() {
      var inputElement = this.$refs.input;
      return Boolean(inputElement && inputElement.selectionStart !== inputElement.selectionEnd);
    },
    internalValue: function() {
      return this.controlledValue || this.inputValue || "";
    },
    displayValue: function() {
      if (this.autoFillEnabled) {
        return getDisplayValue(this.internalValue, this.suggestedDisplayValue);
      }
      return this.internalValue;
    },
    controlledValue: function() {
      var value = this.value;
      if (value === void 0 || typeof value === "string") {
        return value;
      }
      return void 0;
    }
  },
  watch: {
    internalValue: function(value) {
      var _this = this;
      var inputElement = this.$refs.input;
      var differenceIndex = 0;
      var suggestedDisplayValue = this.suggestedDisplayValue;
      if (this.autoFillEnabled && value && suggestedDisplayValue && doesTextStartWith(suggestedDisplayValue, value)) {
        var shouldSelectFullRange = false;
        if (shouldSelectFullRange && inputElement) {
          this.$nextTick(function() {
            inputElement.setSelectionRange(0, suggestedDisplayValue.length, SELECTION_BACKWARD);
          });
        } else {
          while (differenceIndex < value.length && value[differenceIndex].toLocaleLowerCase() === suggestedDisplayValue[differenceIndex].toLocaleLowerCase()) {
            differenceIndex++;
          }
          if (differenceIndex > 0 && inputElement) {
            this.$nextTick(function() {
              inputElement.setSelectionRange(differenceIndex, suggestedDisplayValue.length, SELECTION_BACKWARD);
            });
          }
        }
      } else if (inputElement) {
        if (this.cursor !== null && !this.autoFillEnabled && !this.isComposing) {
          this.$nextTick(function() {
            inputElement.setSelectionRange(_this.cursor.start, _this.cursor.end, _this.cursor.dir);
          });
        }
      }
    }
  },
  beforeDestroy: function() {
    clearTimeout(this.timeout);
  },
  methods: {
    focus: function() {
      var inputElement = this.$refs.input;
      inputElement && inputElement.focus();
    },
    clear: function() {
      var inputElement = this.$refs.input;
      this.autoFillEnabled = false;
      this.updateValue("", false);
      inputElement && inputElement.setSelectionRange(0, 0);
    },
    getCurrentInputValue: function(ev) {
      var inputElement = this.$refs.input;
      if (ev && ev.target && ev.target.value) {
        return ev.target.value;
      } else if (inputElement && inputElement.value) {
        return inputElement.value;
      } else {
        return "";
      }
    },
    onCompositionStart: function() {
      this.isComposing = true;
      this.autoFillEnabled = false;
    },
    onCompositionUpdate: function() {
      if (isIE11()) {
        this.updateValue(this.getCurrentInputValue(), true);
      }
    },
    onCompositionEnd: function() {
      var _this = this;
      var inputValue = this.getCurrentInputValue();
      this.tryEnableAutofill(inputValue, this.internalValue, false, true);
      this.isComposing = false;
      this.timeout = window.setTimeout(function() {
        _this.updateValue(_this.getCurrentInputValue(), false);
      }, 0);
    },
    updateValue: function(newValue, composing) {
      if (!newValue && newValue === this.internalValue) {
        return;
      }
      this.inputValue = newValue;
      this.$emit("input", newValue, composing);
    },
    tryEnableAutofill: function(newValue, oldValue, isComposing, isComposed) {
      var inputElement = this.$refs.input;
      if (!isComposing && newValue && inputElement && inputElement.selectionStart === newValue.length && !this.autoFillEnabled && (newValue.length > oldValue.length || isComposed)) {
        this.autoFillEnabled = true;
      }
    },
    onInput: function(ev) {
      var value = this.getCurrentInputValue(ev);
      if (!this.isComposing) {
        this.tryEnableAutofill(value, this.internalValue, ev.isComposing);
      }
      if (!(isIE11() && this.isComposing)) {
        var nativeEventComposing = ev.isComposing;
        var isComposing = nativeEventComposing === void 0 ? this.isComposing : nativeEventComposing;
        this.updateValue(value, isComposing);
      }
    },
    onKeyDown: function(ev) {
      if (ev.isComposing)
        return;
      switch (ev.which) {
        case KeyCodes.backspace:
          this.autoFillEnabled = false;
          break;
        case KeyCodes.left:
        case KeyCodes.right:
          if (this.autoFillEnabled) {
            this.inputValue = this.suggestedDisplayValue || "";
            this.autoFillEnabled = false;
          }
          break;
        default:
          if (!this.autoFillEnabled) {
            if (this.enableAutofillOnKeyPress.indexOf(ev.which) !== -1) {
              this.autoFillEnabled = true;
            }
          }
          break;
      }
    },
    onClick: function() {
      if (this.internalValue && this.internalValue !== "" && this.autoFillEnabled) {
        this.autoFillEnabled = false;
      }
    }
  },
  render: function(h) {
    return h("input", {
      ref: "input",
      attrs: __assign({ autoCapitalize: "off", autoComplete: "off", "aria-autocomplete": "both", "data-lpignore": true, disabled: this.disabled }, this.$attrs),
      domProps: {
        value: this.displayValue
      },
      on: {
        compositionstart: this.onCompositionStart,
        compositionupdate: this.onCompositionUpdate,
        compositionend: this.onCompositionEnd,
        input: this.onInput,
        keydown: this.onKeyDown,
        click: this.onClick
      }
    });
  }
});
function getDisplayValue(inputValue, suggestedDisplayValue) {
  var displayValue = inputValue;
  if (suggestedDisplayValue && inputValue && doesTextStartWith(suggestedDisplayValue, displayValue)) {
    displayValue = suggestedDisplayValue;
  }
  return displayValue;
}
function doesTextStartWith(text, startWith) {
  if (!text || !startWith) {
    return false;
  }
  return text.toLocaleLowerCase().indexOf(startWith.toLocaleLowerCase()) === 0;
}

export { Autofill };
