<template>
  <div
    class="tabs"
    :class="{
      'tabs--full-height': fullHeight,
      'tabs--large-offset': largeOffset,
      'tabs--nopadding': noPadding,
      'tabs--grow-items': growItems,
    }"
  >
    <ul class="tabs__header">
      <li
        v-for="(tab, index) in tabs"
        :key="`${tab.title} ${tab.tooltip}`"
        v-tooltip="tab.tooltip"
        class="tabs__item"
        :class="{
          'tabs__item--active': isActive(index),
          'tabs__item--disabled': tab.disabled,
        }"
        @click="
          tab.disabled ? $emit('click-disabled', index) : selectTab(index)
        "
      >
        <a
          :href="getHref(index)"
          class="tabs__link"
          :class="{ 'tabs__link--disabled': tab.disabled }"
          @click.prevent
        >
          <i v-if="tab.icon" :class="tab.icon"></i>
          {{ tab.title }}
          <i v-if="tab.appendIcon" :class="tab.appendIcon"></i>
        </a>
      </li>
    </ul>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'Tabs',
  props: {
    /**
     * The index of the selected tab.
     */
    selectedIndex: {
      type: Number,
      required: false,
      default: 0,
    },
    /**
     * Whether the tabs should take the full height of the parent.
     */
    fullHeight: {
      type: Boolean,
      required: false,
      default: false,
    },
    /**
     * The Vue route object. If provided the tabs will be used for navigation.
     * and the active tab will be set according to the current route.
     * The child Tab components should have a `to` prop set.
     */
    route: {
      type: Object,
      required: false,
      default: null,
    },
    /**
     * Whether the tabs container should add some extra space to the left.
     */
    largeOffset: {
      type: Boolean,
      required: false,
      default: false,
    },
    /**
     * Removes the padding from the tabs container and header.
     */
    noPadding: {
      type: Boolean,
      required: false,
      default: false,
    },
    /**
     * Whether the tabs header items should grow to use all the available space.
     */
    growItems: {
      type: Boolean,
      required: false,
      default: false,
    },
  },
  data() {
    return {
      internalSelectedIndex: 0, // In case the prop isn't used by a parent
      tabs: [], // all the tabs
    }
  },
  watch: {
    selectedIndex: {
      handler(i) {
        if (!this.route && i !== undefined) {
          this.internalSelectedIndex = i
        }
      },
      immediate: true,
    },
  },
  created() {
    this.tabs = this.$children
  },
  mounted() {
    if (this.route) {
      this.tabs.forEach((tab) => {
        tab.isActive = this.route.name === tab.to.name
      })
    } else this.selectTab(this.internalSelectedIndex)
  },
  methods: {
    isActive(i) {
      if (this.route) return this.route.name === this.tabs[i].to.name
      else return this.internalSelectedIndex === i
    },
    getHref(i) {
      if (this.route) {
        const tab = this.tabs[i]
        return !tab.disabled ? this.$router.match(tab.to).path : null
      }
      return null
    },
    selectTab(i) {
      if (this.route) {
        this.$emit('update:selectedIndex', i)
        this.$router.push(this.tabs[i].to)
      } else {
        this.$emit('update:selectedIndex', i)
        this.internalSelectedIndex = i
      }
      this.tabs.forEach((tab, index) => {
        tab.isActive = index === i
      })
    },
  },
}
</script>