<template>
  <fieldset class="mc-field mc-field--group">
    <legend v-if="legend" class="mc-field__legend">
      {{ legend }}
      <span
        v-if="requirementText"
        class="mc-field__requirement"
        aria-hidden="true"
      >
        {{ requirementText }}
      </span>
    </legend>
    <span v-if="helpId && helpText" :id="helpId" class="mc-field__help">
      {{ helpText }}
    </span>
    <div
      class="mc-field__container"
      :class="{ 'mc-field__container--inline': inline }"
    >
      <MCheckbox
        v-for="(option, index) in options"
        v-bind="option"
        :key="option.id ? option.id : option.value"
        root-class="mc-field__item"
        :disabled="option.disabled || disabled"
        :model-value="
          modelValue ? modelValue.includes(option.value) : undefined
        "
        @update:model-value="(v) => onChange(v, option.value)"
      >
        <template #label>
          <!-- @slot Use this slot if you want to customise the label display of each MCheckbox element -->
          <slot :name="`label${index + 1}`" :option="option">
            {{ option.label }}
          </slot>
        </template>
      </MCheckbox>
    </div>
    <span
      v-if="errorId && errorMessage"
      :id="errorId"
      class="mc-field__error-message"
    >
      {{ errorMessage }}
    </span>
  </fieldset>
</template>

<script>
import MCheckbox from './MCheckbox.vue';

/**
 * > Checkboxes are used to select one or multiple options in a list. They usually find their place in forms and are also used to accept some mentions.
 *
 * The `MCheckboxGroup` component is the **Vue.js** implementation of the **Checkbox group** component of Mozaic Design System.<br/>
 * The full specification of this component is available in [the associated documentation](https://mozaic.adeo.cloud/components/form/checkbox/#checkbox-group).
 */
export default {
  name: 'MCheckboxGroup',
  components: {
    MCheckbox,
  },
  props: {
    /**
     * Label of the whole group of checkboxes
     */
    legend: {
      type: String,
      default: undefined,
    },
    /**
     * Property used to manage the values checked by v-model
     * (Do not use directly)
     * @ignore
     */
    modelValue: {
      type: Array,
      default: undefined,
    },
    /**
     * An array of objects to provide all the values and attributes related to a checkbox
     */
    options: {
      type: Array,
      default: undefined,
    },
    /**
     * Text that indicate if one or more elements of the group are mandatory
     */
    requirementText: {
      type: String,
      default: undefined,
    },
    /**
     * Text providing relevant or additional information to ensure that the user understands the purpose of the selection.
     */
    helpText: {
      type: String,
      default: undefined,
    },
    /**
     * For accessibility reasons a `helpId` must be defined when using a `helpText`
     */
    // TODO: See if it is possible to automatically generate this id in the @next version
    helpId: {
      type: String,
      default: undefined,
    },
    /**
     * Text below the group of checkboxes explaining the reason for the error following the user selection.
     */
    errorMessage: {
      type: String,
      default: undefined,
    },
    /**
     * For accessibility reasons a `errorId` must be defined when using a `errorMessage`
     */
    // TODO: See if it is possible to automatically generate this id in the @next version
    errorId: {
      type: String,
      default: undefined,
    },
    /**
     * Position the inputs horizontally
     */
    inline: {
      type: Boolean,
      default: false,
    },
    /**
     * Disabled all checkboxes
     */
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['update:modelValue'],
  data() {
    return {
      localValue: this.modelValue ?? [],
    };
  },
  watch: {
    modelValue: {
      handler(newValue) {
        this.localValue = newValue;
      },
    },
  },
  methods: {
    onChange(isChecked, value) {
      let values = this.localValue;

      if (isChecked && !values.includes(value)) {
        values.push(value);
      } else {
        values = values.filter((key) => key !== value);
      }

      /**
       * Triggered each time a checkbox is checked/unchecked. _(can be used with a v-model)_
       */
      this.$emit('update:modelValue', values);
      this.localValue = values;
    },
  },
};
</script>

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