<script setup>
import {defineProps, defineSlots, onMounted, ref, watch, defineEmits} from 'vue';
import { useRouter } from 'vue-router';

const props = defineProps({
  /**
   * The tabs to display
   * @example
   * [
   *  { name: 'Tab 1', slot: 'tab1', icon: 'fas fa-home' }
   *  { name: 'Tab 2', slot: 'tab2', icon: 'fas fa-user', hidden: true }
   *  { name: 'Tab 3', slot: 'tab3', hidden: () => { return false; } }
   *  ]
   */
  tabs: {
    type: Array,
    required: true,
    default: []
  },
  /**
   * The default active tab (slot name)
   * @example 'tab1'
   */
  defaultActiveTab: {
    type: String,
    required: true
  },
  /**
   * Allow the tabs to be compact when there is only one tab
   * @default false
   */
  allowCompactWhenOneTab: {
    type: Boolean,
    default: false
  },
  /**
   * Forcefully set the active tab
   * @default null
   * @type String
   */
  forceActiveTab: {
    type: String,
    default: null
  },
});

const slots = defineSlots();
const emit = defineEmits(['update:activeTab']);
const visibleTabs = ref([]);
/**
 * The active tab
 * The is by default the prop defaultActiveTab, but can be changed by the user and won't be emitted, as it is not a prop.
 */
const activeTab = ref(props.defaultActiveTab);
/**
 * Update the visible tabs
 * This checks if the tab is hidden or not, and returns the visible tabs
 */
const updateVisibleTabs = () => {
  // Loop through the tabs and set the visible tabs
  console.log('Updating visible tabs');
  const tmp_visibleTabs = [];
  props.tabs.forEach((tab) => {
    if (typeof tab.hidden === 'function') {
      if (!tab.hidden()) {
        tmp_visibleTabs.push(tab);
      }
    } else if (typeof tab.hidden === 'boolean') {
      if (!tab.hidden) {
        tmp_visibleTabs.push(tab);
      }
    } else {
      if (!tab.hidden) {
        tmp_visibleTabs.push(tab);
      }
    }
  });
  visibleTabs.value = tmp_visibleTabs;
  // If the active tab is not visible, set the active tab to the first visible tab
  if (!visibleTabs.value.find((tab) => tab.slot === activeTab.value)) {
    activeTab.value = visibleTabs.value[0].slot;
  }
};
// Update the visible tabs every time the slot changes (If the tabs is a reactive object)
if (typeof props.tabs === 'object' && props.tabs.value !== undefined) {
  watch(props.tabs, () => {
    updateVisibleTabs();
  });
}

// Update the visible tabs when the component is mounted
onMounted(() => {
  updateVisibleTabs();
});

// Update the visible tabs when the current active tab changes "Hidden" status
watch(activeTab, () => {
  updateVisibleTabs();
});

const isTabVisible = (tab) => {
  let tmp_visible = null
  console.log('Checking if tab is hidden', tab);
  switch (typeof tab.hidden) {
    case 'function':
      console.log('Tab is hidden function');
      tmp_visible = !tab.hidden();
      break;
    case 'boolean':
      console.log('Tab is hidden boolean');
      tmp_visible = !tab.hidden;
      break;
    default:
      console.log('Tab is hidden default');
      tmp_visible = !tab.hidden;
      break;
  }
  console.log('Tab is visible', tmp_visible);
  // If the tab is the current active tab, and the tab is not visible, set the active tab to the first visible tab
  if (tab.slot === activeTab.value && !tmp_visible) {
    activeTab.value = visibleTabs.value[0].slot;
  }
  return tmp_visible;
};

const onClickTab = (tab) => {
  // If the tab is not visible, do nothing
  if (!isTabVisible(tab)) {
    return;
  }
  // Set the active tab to the clicked tab
  if (props.forceActiveTab === null || props.forceActiveTab === undefined) {
    activeTab.value = tab;
  }
  // Emit the active tab
  emit('update:activeTab', tab);
};

// Watch the forceActiveTab prop and set the active tab to the forceActiveTab value
watch(() => props.forceActiveTab, (newValue) => {
  if (newValue !== null && newValue !== undefined) {
    activeTab.value = newValue;
  }
});

if (props.forceActiveTab !== null && props.forceActiveTab !== undefined) {
  activeTab.value = props.forceActiveTab;
}

</script>
<template>
  <div>
    <!-- Display the tabs, if there are more than one tab (and the compact mode is not allowed) -->
    <div
        class="tabs is-centered is-fullwidth"
        v-if="props.allowCompactWhenOneTab"
    >
      <ul>
        <template
            v-if="props.tabs"
            v-for="(tab, index) in props.tabs"
            :key="index"
        >
          <li
              :class="{ 'is-active': tab.slot === activeTab }"
              v-if="isTabVisible(tab)"
          >
            <a @click="onClickTab(tab.slot)">
              <!-- Display the tab icon (if any) -->
              <span v-if="tab.icon" class="icon is-small">
                <i :class="tab.icon"></i>
              </span>
              <!-- Display the tab name -->
              <span>
                {{ tab.name }}
              </span>
            </a>
          </li>
        </template>
      </ul>
    </div>
    <!-- Display the content of the active tab -->
    <div>
      <template v-for="(tab, index) in props.tabs" :key="index">
        <template v-if="slots[tab.slot] && tab.slot === activeTab">
          <slot :name="tab.slot"></slot>
        </template>
      </template>
    </div>
  </div>
</template>

<style scoped>

</style>