<template>
  <div class="mc-tabs" :class="classObject">
    <ul role="tablist" class="mc-tabs__nav" :aria-label="description">
      <li
        v-for="(tab, index) in tabs"
        :key="`tab-${index}`"
        role="presentation"
        class="mc-tabs__item"
      >
        <component
          :is="setTabElement(tab)"
          :id="tab.id"
          v-bind="setTabAttributes(tab, index)"
          ref="tab"
          role="tab"
          class="mc-tabs__element"
          :class="setTabClass(tab, index)"
          @click="onTabClicked($event, tab, index)"
        >
          <div class="mc-tabs__text">
            <MIcon v-if="tab.icon" :name="tab.icon" class="mc-tabs__icon" />
            <span>{{tab.label}}</span>
          </div>
        </component>
      </li>
    </ul>
  </div>
</template>

<script>
import MIcon from '../icon/MIcon.vue';

/**
 * > Tabs allow the user to navigate from a content to another within the same context. It keeps the user on the same page.
 *
 * The `MTab` component is the **Vue.js** implementation of the **Tabs** component of Mozaic Design System.<br/>
 * The full specification of this component is available in [the associated documentation](https://mozaic.adeo.cloud/components/tabs/).
 */
export default {
  name: 'MTabsV2',
  components: {
    MIcon,
  },
  props: {
    /**
     * An array of objects that allows you to provide all the data needed to generate the content for each tab
     * @type {[{ label: String, icon: MozaicIconName, href: String, router: 'router-link', to: String, disabled: Boolean }]}
     */
    tabs: {
      type: Array,
      required: true,
    },
    /**
     * A description indicating the purpose of the set of tabs. Useful for improving the accessibility of the component.
     * @see [Accessibility and semantic](https://mozaic.adeo.cloud/components/tabs/code/#accessibility-and-semantic)
     */
    description: {
      type: String,
      default: 'Tabs',
    },
    /**
     * Defines how the component will be aligned within the page
     * @values auto, full, centered
     * @see [Variations](https://mozaic.adeo.cloud/components/tabs/#variations)
     */
    align: {
      type: String,
      default: 'auto',
      validator: (value) => ['auto', 'full', 'centered'].includes(value),
    },
    /**
     * Allows to show or hide the divider. This value is set to false _(show)_ by default
     * @see [Variations](https://mozaic.adeo.cloud/components/tabs/#without-divider)
     */
    nodivider: {
      type: Boolean,
      default: false,
    },
    /**
     * Allows to set the active tab.
     * @deprecated
     */
    modelValue: {
      type: Number,
      default: 0,
    },
  },
  emits: ['update:modelValue', 'tab-clicked'],
  data() {
    return {
      localActiveIndex: this.modelValue ?? 0,
    };
  },
  computed: {
    classObject() {
      return {
        'mc-tabs--full': this.align === 'full',
        'mc-tabs--full-centered': this.align === 'centered',
        'mc-tabs--no-divider': this.nodivider,
      };
    },
  },
  watch: {
    modelValue: {
      handler(newValue) {
        this.localActiveIndex = newValue;
      },
    },
  },
  methods: {
    setTabElement(tab) {
      const tabElement = tab.href ? (tab.disabled ? 'span' : 'a') : 'button';
      const routerElement = tab.router ?? null;

      return routerElement ?? tabElement;
    },
    setTabAttributes(tab, index) {
      const href = tab.href ? (tab.disabled ? null : tab.href) : null;
      const type = !tab.href ? 'button' : null;
      const disabled = !tab.href && tab.disabled ? true : null;
      const to = tab.to ?? null;

      return {
        ...tab.attrs,
        href,
        to,
        type,
        disabled,
        'aria-selected': this.isTabActive(index).toString(),
      };
    },
    setTabClass(tab, index) {
      return [
        tab.class,
        {
          'mc-tabs__element--selected': this.isTabActive(index),
          'mc-tabs__element--disabled': tab.disabled,
        },
      ];
    },
    onTabClicked(event, tab, tabIndex) {
      if (tab && tab.disabled) {
        event.preventDefault();

        return;
      }

      if (tabIndex !== this.localActiveIndex) {
        this.localActiveIndex = tabIndex;
        /**
         * Triggers when the value of the selected tab index changed
         *
         * - @arg {number} [tab] - value of the selected tab index
         */
        this.$emit('update:modelValue', this.localActiveIndex);
      }

      if (event) {
        /**
         * Triggers when a tab is clicked.
         *
         * - @arg {object} [tab] - a js object of values & datas of the tab clicked
         */
        this.$emit('tab-clicked', { index: tabIndex, ...tab });
      }
    },
    isTabActive(index) {
      return this.localActiveIndex === index;
    },
  },
};
</script>

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