<script setup lang="ts">
import type { Tab } from '@bagelink/vue'
import { Icon } from '@bagelink/vue'
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useTabs } from './tabsManager'

const props = defineProps<{
	title?: string
	tabs: Tab[]
	modelValue?: string
	sideTabs?: boolean
	group: string
	flat?: boolean
	vertical?: boolean
}>()

const emit = defineEmits(['update:modelValue'])
const { currentTab } = useTabs(props.group)
currentTab.value
	= props.modelValue || typeof props.tabs[0] === 'string'
		? props.tabs[0]
		: props.tabs[0].value

const tabsWrap = ref<HTMLElement | undefined>(undefined)
const tabs = ref<HTMLElement[]>([])

function updateIndicator() {
	nextTick(() => {
		if (!tabsWrap.value) { return }
		const activeTab = tabs.value.find(tab => tab.classList.contains('active'))
		if (activeTab) {
			// Wait a bit more to ensure CSS is fully loaded and elements are properly sized
			setTimeout(() => {
				const { offsetLeft, offsetWidth } = activeTab
				if (offsetLeft >= 0 && offsetWidth > 0) { // Ensure valid measurements
					tabsWrap.value?.style.setProperty('--indicator-left', `${offsetLeft}px`)
					tabsWrap.value?.style.setProperty('--indicator-width', `${offsetWidth}px`)
					tabsWrap.value?.style.setProperty('--indicator-opacity', '1')
				}
			}, 10)
		}
	})
}

function selectTab(tab: Tab) {
	currentTab.value = typeof tab === 'string' ? tab : tab.value
	emit('update:modelValue', currentTab.value)
	nextTick(() => { updateIndicator() })
}

function isActive(tab: Tab) {
	if (typeof tab === 'string') { return currentTab.value === tab }
	return currentTab.value === tab.value
}

function tabLabel(tab: Tab) {
	if (typeof tab === 'string') { return tab }
	return tab.label
}

watch(
	() => props.modelValue,
	(value) => {
		if (value && !isActive(value)) { currentTab.value = value }
		nextTick(() => { updateIndicator() })
	},
	{ immediate: true }
)

onMounted(() => {
	tabs.value = Array.from(tabsWrap.value?.querySelectorAll('.bgl_tab') || [])

	// Wait for the next frame to ensure all CSS and layout calculations are done
	requestAnimationFrame(() => {
		updateIndicator()
	})

	window.addEventListener('resize', updateIndicator)
})

watch(
	() => tabs.value,
	() => {
		nextTick(() => { updateIndicator() })
	},
	{ deep: true }
)
onBeforeUnmount(() => {
	window.removeEventListener('resize', updateIndicator)
})
</script>

<template>
	<div ref="tabsWrap" class="grid auto-flow-columns relative fit-content bgl_tabs_wrap overflow-hidden" :class="{ 'bgl_flat-tabs': flat, 'bgl_vertical-tabs': vertical }">
		<slot name="tabs" v-bind="{ selectTab, isActive, tabLabel, tabs }">
			<button v-for="(tab, i) in props.tabs" :key="i" type="button" :class="{ active: isActive(tab) }" class="bgl_tab relative z-1" @click="selectTab(tab)">
				<Icon v-if="typeof tab !== 'string' && tab.icon" :icon="tab.icon" />
				{{ tabLabel(tab) }}
			</button>
		</slot>
	</div>
</template>

<style>
:root {
	--bgl_tabs-background: var(--input-bg);
	--bgl_tabs-border-radius: var(--input-border-radius);
	--bgl_tabs-inline-padding: calc(var(--btn-padding) / 8);
	--bgl_tabs-block-padding: calc(var(--btn-padding) / 8);
	--bgl_tabs-shadow: inset 0 0 10px #00000012;
	--bgl_tabs-gap: 0.25rem;
	--bgl_tabs-font-size: var(--input-font-size);
	--bgl_tab-inline-padding: calc(var(--btn-padding) / 2);
	--bgl_tab-block-padding: calc(var(--btn-padding) / 8);
	--bgl_tab-gap: 0.5rem;
	--bgl_tabs-border-radius: var(--input-border-radius);
	--bgl-tab-hover-bg: rgba(255, 255, 255, .4);
	--bgl_tabs-indicator-color: var(--bgl-popup-bg);
	--bgl-tabs-flat-indicator-color: var(--bgl-primary);
}
</style>

<style scoped>
.bgl_tabs_wrap {
	background: var(--bgl_tabs-background);
		border-radius: calc(var(--bgl_tabs-border-radius) * 1.4);
		padding-inline: var(--bgl_tabs-inline-padding);
		padding-block: var(--bgl_tabs-block-padding);
		box-shadow: var(--bgl_tabs-shadow);
		gap: var(--bgl_tabs-gap);
}

.bgl_tab {
	border: none;
	background: transparent;
	cursor: pointer;
	font-size: var(--bgl_tabs-font-size);
	font-family: inherit;
	padding-inline: var(--bgl_tab-inline-padding);
		padding-block: var(--bgl_tab-block-padding);
		border-radius: var(--bgl_tab-border-radius);
	transition: var(--bgl-transition);
	color: inherit;
	display: flex;
		align-items: center;
		gap: var(--bgl_tab-gap);
}

.bgl_tab:hover {
	background: var(--bgl-tab-hover-bg);
}

.bgl_tabs_wrap::before {
	content: '';
	position: absolute;
	top: var(--bgl_tabs-block-padding);
		bottom: var(--bgl_tabs-block-padding);
	left: var(--indicator-left, 0);
	width: var(--indicator-width, 0);
	background: var(--bgl_tabs-indicator-color);
		border-radius: var(--bgl_tabs-border-radius);
	transition: var(--bgl-transition);
	z-index: 0;
	/* Hide indicator initially until position is calculated */
	opacity: var(--indicator-opacity, 0);
}
.bgl_flat-tabs.bgl_tabs_wrap {
	background: transparent;
	box-shadow: none;
}
.bgl_flat-tabs.bgl_tabs_wrap::before{
	background: transparent;
	border-bottom: 1px solid var(--bgl-tabs-flat-indicator-color);
	border-radius: 0;
	top: calc(var(--btn-padding) * 1.25);
	bottom: unset;

}
.bgl_flat-tabs .active.bgl_tab{
	color: var(--bgl-primary)
}
.bgl_flat-tabs .bgl_tab:hover {
	background: rgba(255, 255, 255, .1);
}
.bgl_vertical-tabs{
	grid-auto-flow: row;
	align-items: start;
	justify-items: start;
	gap: 1rem
}
.bgl_vertical-tabs .bgl_tab{
	padding-inline: 0;
	border-radius: 0;
	border-bottom: 1px solid transparent;
}
.bgl_vertical-tabs .bgl_tab:hover{
	background: transparent;
	border-bottom: 1px solid var(--bgl-tabs-flat-indicator-color);

}
.bgl_vertical-tabs .bgl_tab.active{
	border-bottom: 1px solid var(--bgl-tabs-flat-indicator-color);
}
.bgl_vertical-tabs.bgl_tabs_wrap::before{
	border: none;
}
@media screen and (max-width: 910px) {
	.bgl_vertical-tabs{
	grid-auto-flow: column;
	overflow: auto;
	max-width: 100vw;
	padding-inline-end: 1rem;
	width: 100%;
	gap: 1rem;
	position: relative;
}
.bgl_vertical-tabs::-webkit-scrollbar {
	display: none;
}
.bgl_vertical-tabs .bgl_tab{
	white-space: nowrap;
}
				.bgl_tab {
					gap: 0.25rem;
					padding: 0.25rem 0.5rem;
				}
}
</style>
