<template>
  <select
    ref="select"
    class="mc-select"
    :class="classObject"
    :value="getSelectValue"
    :disabled="disabled"
    @change="onChange($event.target.value)"
  >
    <option v-if="placeholder" value="" disabled="disabled">
      -- {{ placeholder }} --
    </option>
    <option
      v-for="(option, index) in options"
      :key="index"
      :value="option.value"
      v-bind="option.attributes"
      :disabled="option.disabled"
    >
      <!-- @slot Use this slot if you wish to customise the display of text for `<option>` elements of the MSelect -->
      <slot name="text" :option="option">
        {{ option.text }}
      </slot>
      <!-- @slot Use this slot if you wish to add `<option>` elements as full HTML Tags -->
      <slot name="options" />
    </option>
  </select>
</template>

<script>
/**
 * > A select is a selection tool used in forms, allowing user to choose between multiple predefined options.
 *
 * The `MSelect` component is the **Vue.js** implementation of the **Select** component of Mozaic Design System.<br/>
 * The full specification of this component is available in [the associated documentation](https://mozaic.adeo.cloud/components/form/select/).
 */
export default {
  name: 'MSelect',
  props: {
    /**
     * An array of objects that allows you to provide all the data needed to generate the options tags
     */
    options: {
      type: Array,
      required: true,
    },
    /**
     * The value of the component.
     */
    modelValue: {
      type: [String, Number],
      default: null,
    },
    /**
     * Allows to define the size of the MSelect
     * @values s, m
     */
    size: {
      type: String,
      default: 'm',
      validator: (value) => ['s', 'm'].includes(value),
    },
    /**
     * The MSelect placeholder
     */
    placeholder: {
      type: String,
      default: null,
    },
    /**
     * Allows to define the component as valid
     */
    isValid: {
      type: Boolean,
      default: false,
    },
    /**
     * Allows to define the component as invalid
     */
    isInvalid: {
      type: Boolean,
      default: false,
    },
    /**
     * Allows to disabled the component
     */
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['update:modelValue'],
  data() {
    return {
      optionValue: null,
    };
  },
  computed: {
    classObject() {
      const classes = [
        {
          'is-valid': this.isValid,
          'is-invalid': this.isInvalid,
        },
      ];

      if (this.size) {
        classes.push(`mc-select--${this.size}`);
      }

      return classes;
    },
    getSelectValue() {
      return this.modelValue ? this.modelValue : this.optionValue;
    },
  },
  mounted() {
    this.getOptionValue();
  },
  methods: {
    getOptionValue() {
      if (!this.modelValue) {
        const firstOption = this.$el.querySelector('option');

        if (firstOption) {
          firstOption.selected = true;
        }
      }
    },
    onChange(value) {
      const optionText = this.$refs.select
        .querySelector(`option[value="${value}"]`)
        .textContent.trim();
      const optionData = {
        text: optionText,
        value: value,
      };

      /**
       * Triggered when the MSelect value changes
       */
      this.$emit('update:modelValue', value, optionData);
    },
  },
};
</script>

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