<template>
  <div
    class="mc-stars-input"
    :class="classObject"
  >
    <input
      :id="name + '0'"
      v-model="localModelValue"
      type="radio"
      class="mc-stars-input__radio"
      :name="required ? name + '-unselected' : name"
      value="0"
      :aria-label="unselectedText"
    />
    <template
      v-for="(rateId, index) in ratingValue"
      :key="'ratingInput-' + rateId"
    >
      <input
        :id="name + rateId"
        v-model="localModelValue"
        type="radio"
        class="mc-stars-input__radio"
        :name="name"
        :value="rateId"
        :required="required"
        @click="onClickStar(index)"
      />
      <label
        :for="name + rateId"
        :title="ratingLabels[index]"
        class="mc-stars-input__label"
      >
        <span class="mc-stars-input__text">
          {{ ratingLabels[index] }}
        </span>
      </label>
    </template>
  </div>
</template>

<script>
import { useId } from 'vue';
import {
  responsiveModifiers,
  responsiveModifierValidators,
} from '../../utils/mozaicClasses';

const RATINGVALUE = 5;

/**
 * > Rating stars is a pattern you'll find in almost every website. This allows the user to rate a product or a service. The user can only give an integer rate from 0 to 5 by clicking the corresponding star.
 *
 * The `MStarsInput` component is the **Vue.js** implementation of the **Rating stars input** component of Mozaic Design System.<br/>
 * The full specification of this component is available in [the associated documentation](https://mozaic.adeo.cloud/components/rating-stars/#rating-stars-input).
 */
export default {
  name: 'MStarsInput',
  inheritAttrs: false,
  props: {
    /**
     * The value of the `name` HTML attribute for the stars elements
     */
    name: {
      type: String,
      default: 'rating',
    },
    /**
     * The size of the stars
     * @values s, m, l, xl
     */
    size: {
      type: String,
      default: 'm',
      validator: (value) =>
        responsiveModifierValidators(value, ['s', 'm', 'l', 'xl']),
    },
    /**
     * An array to provide accessible labels for each star
     */
    ratingLabels: {
      type: Array,
      default() {
        return ['Very bad', 'Bad', 'Medium', 'Good', 'Excellent'];
      },
      validator: function (value) {
        return (
          value.length === RATINGVALUE &&
          value.every((item) => typeof item === 'string')
        );
      },
    },
    /**
     * Value of the aria-label attribute set on the empty star element
     */
    unselectedText: {
      type: String,
      default: 'No value',
    },
    /**
     * Allows you to make mandatory the entry of a value
     */
    required: {
      type: Boolean,
      default: false,
    },
    /**
     * Value of the selected star. _(Can be used with a v-model)_
     */
    modelValue: {
      type: Number,
      default: 0,
    },
  },
  emits: ['star-clicked', 'update:modelValue'],
  setup() {
    return {
      id: useId(),
    };
  },
  data() {
    return {
      ratingValue: RATINGVALUE,
    };
  },
  computed: {
    classObject() {
      const classes = [];

      if (this.size) {
        responsiveModifiers('mc-stars-input', this.size, classes);
      }

      return classes;
    },
    localModelValue: {
      get() {
        return this.modelValue;
      },
      set(value) {
        this.$emit('update:modelValue', value);
      },
    },
  },
  methods: {
    onClickStar(index) {
      /**
       * Triggers when a star is clicked
       *
       * - @arg {number} [index] - the index of the clicked star
       */
      this.$emit('star-clicked', index + 1);
    },
  },
};
</script>

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