<template>
  <div
    class="vc-tabs__nav-wrap"
  >
    <div
      ref="navScrollContainer"
      class="vc-tabs__nav-scroll"
    >
      <div
        ref="tabNavList"
        :class="{
          'is--stretch': stretch && !isCardType
        }"
        class="vc-tabs__nav"
        role="tablist"
        @keydown="changeTab"
      >
        <div
          v-for="(tabItem, index) in tabItems"
          :key="tabItem.props.name || `tab-${index}`"
          :class="[{
            'is--active': isActiveTab(tabItem),
            'is--disabled': tabItem.props.disabled
          }, tabItem.navClass]"
          :tabindex="isActiveTab(tabItem) ? 0 : -1"
          role="tab"
          class="vc-tabs__item"
          @click.stop="setActiveTab(tabItem, index)"
        >
          <slot
            v-if="tabItem.slots?.label"
            :tab="tabItem"
            name="tabs-nav-item"
          >
            <component
              :is="tabItem.slots.label"
            />
          </slot>
          <template v-else>
            <i
              v-if="tabItem.icon"
              :class="tabItem.icon"
              class="tabs-nav-icon"
            />
            <span
              v-if="tabItem.label"
              class="vc-tabs__item-text px-1"
            >
              {{ tabItem.label }}
            </span>
            <i
              v-if="tabItem.props.closable && !tabItem.props.disabled"
              class="vc-icon-close icon-xxs icon-closable"
              @click.stop="closeTab(tabItem, index)"
            />
          </template>
        </div>
        <div
          ref="activeBar"
          class="vc-tabs__active-bar"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
// TODO: add mobile design
import { defineComponent, PropType } from 'vue'
import { VcPaneType, VcTabsNavigationType } from '@/components/VcTabs/VcTabs.types'

const EVENT_CODE = {
  left: 'ArrowLeft', // 37
  up: 'ArrowUp', // 38
  right: 'ArrowRight', // 39
  down: 'ArrowDown' // 40
}

const ACTIVE_SELECTOR = '.vc-tabs__item.is--active'

export default defineComponent({
  name: 'VcTabsNav',
  props: {
    tabItems: {
      type: Array as PropType<VcPaneType[]>,
      default: () => []
    },
    activeTab: {
      type: [String, Number],
      default: 0
    },
    stretch: {
      type: Boolean,
      default: false
    },
    type: {
      type: String as PropType<VcTabsNavigationType>,
      default: 'default'
    }
  },
  emits: [
    'tab-close',
    'tab-click'
  ],
  computed: {
    isCardType () {
      return this.type === 'card'
    }
  },
  watch: {
    activeTab () {
      this.setBarStyles()
    },
    tabItems: {
      deep: true,
      handler () {
        this.setBarStyles()
      }
    }
  },
  mounted () {
    window.addEventListener('resize', this.setBarStyles, true)
    window.addEventListener('orientationchange', this.setBarStyles, true)
    this.setBarStyles()
  },
  updated () {
    this.setBarStyles()
  },
  unmounted () {
    window.removeEventListener('resize', this.setBarStyles, true)
    window.removeEventListener('orientationchange', this.setBarStyles, true)
  },
  methods: {
    changeTab (e: KeyboardEvent): void {
      const code = e.code
      const { left, right } = EVENT_CODE
      if (![left, right].includes(code)) {
        return
      }
      const tabList = Array.from(
        (e.currentTarget as HTMLDivElement).querySelectorAll<HTMLDivElement>(
          '[role=tab]:not(.is--disabled)'
        )
      )
      const currentIndex = tabList.indexOf(e.target as HTMLDivElement)
      let nextIndex: number
      if (code === left) {
        if (currentIndex === 0) {
          // first
          nextIndex = tabList.length - 1
        } else {
          nextIndex = currentIndex - 1
        }
      } else {
        // right
        if (currentIndex < tabList.length - 1) {
          // not last
          nextIndex = currentIndex + 1
        } else {
          nextIndex = 0
        }
      }
      tabList[nextIndex].focus()
      tabList[nextIndex].click()
    },
    isActiveTab (tab: VcPaneType): boolean {
      return this.activeTab === tab.paneName
    },
    setActiveTab (tabData: VcPaneType, index: number): void {
      if (tabData.props.disabled) {
        return
      }
      this.$emit('tab-click', tabData.paneName, index)
    },
    closeTab (tabData: VcPaneType, index: number): void {
      if (tabData.props.disabled) {
        return
      }
      this.$emit('tab-close', tabData, index)
    },
    setBarStyles (): void {
      if (!this.tabItems.length || this.isCardType) {
        return
      }
      this.$nextTick(() => {
        const bar = this.$refs.activeBar as HTMLElement
        const navList = this.$refs.tabNavList as HTMLElement
        if (bar) {
          const activeTab = navList.querySelector(ACTIVE_SELECTOR) as HTMLElement
          const left = activeTab?.offsetLeft || 0
          const width = activeTab?.getBoundingClientRect().width || 0
          bar.style.width = width + 'px'
          bar.style.transform = `translateX(${left}px)`
        }
      })
    }
  }
})
</script>

<style lang="scss">
  @import "VcTabNav";
</style>
