<template>
  <div class="mc-quantity-selector">
    <MButton
      class="mc-quantity-selector__button-left"
      theme="bordered"
      icon="ControlLess32"
      icon-position="left"
      :aria-label="decrementAriaLabel"
      :aria-controls="id"
      :disabled="disabled ? disabled : currentValue === valuemin"
      :size="small ? 's' : null"
      tabindex="-1"
      type="button"
      aria-hidden="true"
      @click="decrement()"
    />
    <MTextInputField
      :id="id"
      v-model="currentValue"
      type="number"
      class="mc-quantity-selector__input"
      name="quantity-selector-input"
      :aria-label="inputAriaLabel"
      :aria-valuenow="currentValue"
      :aria-valuemin="valuemin"
      :aria-valuemax="valuemax"
      :placeholder="placeholder"
      :size="small ? 's' : null"
      :disabled="disabled"
      role="spinbutton"
      @change="handle(Number($event.target.value))"
      @focus="onFocus"
      @keypress="integerOnly && formatValue($event)"
    />
    <MButton
      class="mc-quantity-selector__button-right"
      theme="bordered"
      icon="ControlMore32"
      icon-position="right"
      :aria-label="incrementAriaLabel"
      :aria-controls="id"
      :disabled="disabled ? disabled : currentValue === valuemax"
      :size="small ? 's' : null"
      tabindex="-1"
      aria-hidden="true"
      type="button"
      @click="increment()"
    />
  </div>
</template>

<script>
import MButton from '../button/MButton.vue';
import MTextInputField from '../textinput/MTextInputField.vue';

/**
 * > The quantity selector is a form element used to enter or select a number. This type of input is best used when the user needs to choose the quantity of a selected item, like a product before adding to cart for example.
 *
 * The `MQuantitySelector` component is the **Vue.js** implementation of the **Quantity selector** component of Mozaic Design System.<br/>
 * The full specification of this component is available in [the associated documentation](https://mozaic.adeo.cloud/components/form/quantity-selector/).
 */
export default {
  name: 'MQuantitySelector',
  components: {
    MButton,
    MTextInputField,
  },
  props: {
    /**
     * The value of the `id` attribute of the input element
     */
    id: {
      type: String,
      default: 'qty-selector',
    },
    /**
     * The value of the component. _(Can be used with `v-model`)_
     */
    modelValue: {
      type: Number,
      default: 0,
    },
    /**
     * @ignore
     * @deprecated
     * TODO: Value has to be removed
     */
    value: {
      type: Number,
      default: 0,
    },
    /**
     * The value of the `aria-label` attribute of the input element
     */
    inputAriaLabel: {
      type: String,
      default: 'Quantity Selector',
    },
    /**
     * The value of the `aria-label` attribute of the decrement button
     */
    decrementAriaLabel: {
      type: String,
      default: 'Decrement',
    },
    /**
     * The value of the `aria-label` attribute of the increment button
     */
    incrementAriaLabel: {
      type: String,
      default: 'Increment',
    },
    /**
     * The value of the `aria-valuemin` attribute of the input element
     * @see [aria-valuemin](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuemin)
     */
    valuemin: {
      type: Number,
      default: 1,
    },
    /**
     * The value of the `aria-valuemax` attribute of the input element
     * @see [aria-valuemax](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuemax)
     */
    valuemax: {
      type: Number,
      default: 100,
    },
    /**
     * @deprecated
     * @ignore
     */
    placeholder: {
      type: String,
      default: null,
    },
    /**
     * Enables the "small" variation of the component
     */
    small: {
      type: Boolean,
      default: false,
    },
    /**
     * Allows to format the input element to accept only integers
     */
    integerOnly: {
      type: Boolean,
      default: false,
    },
    /**
     * Allows to disabled the component
     */
    disabled: {
      type: Boolean,
      default: false,
    },
    /**
     * Allow to manage increment & decrement function by your own
     */
    stateless: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['input', 'increment', 'decrement', 'update:modelValue'],
  data() { 
    return {
      currentValue: (this.modelValue !== undefined && this.modelValue !== null) ? this.modelValue : this.valuemin,
    };
  },
  watch: {
    // whenever question changes, this function will run
    modelValue(value) {
      this.handle(value);
    },
  },
  methods: {
    handle(value) {
      this.currentValue = value;
      if (this.currentValue > this.valuemax) {
        this.currentValue = this.valuemax;
      }
      if (this.currentValue <= this.valuemin) {
        this.currentValue = this.valuemin;
      }
      /**
       * Triggered when entering the field
       * // TODO: This event should be
       * @ignore
       * @deprecated
       */
      this.$emit('input', this.currentValue);
      /**
       * Triggered when entering the field
       */
      this.$emit('update:modelValue', this.currentValue);
    },
    increment() {
      if (this.currentValue < this.valuemax) {
        if (!this.stateless) {
          this.currentValue++;
        }
        this.$emit('update:modelValue', this.currentValue);
        /**
         * Triggered when the increment button is clicked
         */
        this.$emit('increment', this.currentValue);
      }
    },
    decrement() {
      if (this.currentValue > this.valuemin) {
        if (!this.stateless) {
          this.currentValue--;
        }
        this.$emit('update:modelValue', this.currentValue);
        /**
         * Triggered when the decrement button is clicked
         */
        this.$emit('decrement', this.currentValue);
      }
    },
    formatValue(e) {
      const INTEGER_ONLY_REGEX = /[0-9/]+/;
      if (!INTEGER_ONLY_REGEX.test(e.key)) {
        e.preventDefault();
      }
    },
    onFocus(e) {
      e.target.select();
    },
  },
};
</script>

<style lang="scss" scoped>
@import 'settings-tools/all-settings';
@import 'components/c.quantity-selector';
</style>
