<template>
  <div
    :class="[
      {'is--card': navType === 'card'},
      TABS_BASE_CLASS]"
  >
    <div class="vc-tabs__header">
      <VcTabsNav
        ref="tabsNav"
        :active-tab="currentName"
        :tab-items="tabs"
        :stretch="stretch"
        :type="navType"
        @tab-click="onTabClick"
        @tab-close="onTabClose"
      />
    </div>
    <div class="vc-tabs__content">
      <slot />
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'
import VcTabsNav from '@/components/VcTabs/VcTabNav.vue'
import { VcPaneType, VcTabsNavigationType } from '@/components/VcTabs/VcTabs.types'

const TABS_BASE_CLASS = 'vc-tabs'
type modelType = number | string

export default defineComponent({
  name: 'VcTabs',
  components: { VcTabsNav },
  provide () {
    return {
      tabActiveName: this.getCurrentName,
      registerPane: this.onRegisterPane,
      unregisterPane: this.onUnregisterPane
    }
  },
  props: {
    modelValue: {
      type: [Number, String],
      default: ''
    },
    stretch: {
      type: Boolean,
      default: false
    },
    navType: {
      type: String as PropType<VcTabsNavigationType>,
      default: 'default'
    }
  },
  emits: [
    'update:modelValue',
    'tab-change',
    'tab-remove',
    'tab-click'
  ],
  data () {
    return {
      tabs: [] as VcPaneType[],
      TABS_BASE_CLASS: TABS_BASE_CLASS
    }
  },
  computed: {
    currentName: {
      get () {
        return this.modelValue || 0
      },
      set (val: string | number) {
        this.setCurrentName(val)
      }
    }
  },
  methods: {
    getCurrentName (): modelType {
      return this.currentName
    },
    setCurrentName (value?: modelType): void {
      if (value === this.currentName || value === undefined) {
        return
      }
      this.changeCurrentName(value)
    },
    changeCurrentName (value: modelType): void {
      this.$emit('update:modelValue', value)
      this.$emit('tab-change', value)
    },
    onTabClick (tabName: string): void {
      this.currentName = tabName
      this.$emit('tab-click', tabName)
    },
    onTabClose (tabData: VcPaneType): void {
      this.$emit('tab-remove', tabData.paneName, tabData)
    },
    onRegisterPane (pane: VcPaneType): void {
      const _tabs = [...this.tabs]
      if (!_tabs.length) {
        _tabs.push(pane)
      } else {
        const _index = pane.props.index || _tabs.length
        _tabs.splice(_index, 0, pane)
      }

      this.tabs = _tabs
      if (!this.currentName) {
        this.currentName = this.tabs[0]?.paneName
      }
    },
    onUnregisterPane (paneName: string | number): void {
      this.tabs = this.tabs.filter((item: VcPaneType) => item.paneName !== paneName)
    },
    setFirstActiveTab (): void {
      if (this.tabs.length) {
        this.currentName = !this.tabs[0].disabled ? this.tabs[0].paneName : ''
      }
    },
    setLastActiveTab (): void {
      if (this.tabs.length) {
        const lastTab = this.tabs[this.tabs.length - 1]
        this.currentName = !lastTab.disabled ? lastTab.paneName : ''
      }
    },
    togglePreviousTab (): void {
      if (this.tabs.length) {
        const activeIndex = this.tabs.findIndex((item:VcPaneType) => item.paneName === this.currentName)
        if (activeIndex < 0) {
          return
        }
        const prevIndex = this.getPrevIndex(activeIndex, this.tabs)
        this.currentName = this.tabs[prevIndex]?.paneName || ''
      }
    },
    toggleNextTab (): void {
      if (this.tabs.length) {
        const activeIndex = this.tabs.findIndex((item:VcPaneType) => item.paneName === this.currentName)
        if (activeIndex > this.tabs.length - 1) {
          return
        }
        const nextIndex = this.getNextIndex(activeIndex, this.tabs)
        this.currentName = this.tabs[nextIndex]?.paneName || ''
      }
    },
    getPrevIndex (index: number, tabsValues: VcPaneType[]): number {
      let prevIndex = -1
      for (let i = index - 1; i >= 0; i--) {
        if (!tabsValues[i].disabled) {
          prevIndex = i
          break
        }
      }
      return prevIndex
    },
    getNextIndex (index: number, tabsValues: VcPaneType[]): number {
      let nextIndex = -1
      for (let i = index + 1; i < tabsValues.length; i++) {
        if (!tabsValues[i].disabled) {
          nextIndex = i
          break
        }
      }
      return nextIndex
    }
  }
})
</script>

<style lang="scss">
  .vc-tabs {
    .vc-tabs__header {
      @apply h-10 p-0 relative;
      margin: 0 0 15px;
    }
    &.is--card {
      .vc-tabs__header {
        @apply h-auto mb-0;
      }
      .vc-tabs__content {
        @apply p-6 relative rounded-md shadow-card;
      }
    }
  }
</style>
