<script setup lang="ts">
import { ref, computed } from 'vue'

interface TocItem {
  id: string
  depth: number
  text: string
  children?: TocItem[]
}

const props = defineProps<{
  toc: TocItem[]
  maxDepth?: number
}>()

const maxDepth = props.maxDepth ?? 3

const filteredToc = computed(() => {
  const filterByDepth = (items: TocItem[]): TocItem[] => {
    return items
      .filter(item => item.depth <= maxDepth)
      .map(item => ({
        ...item,
        children: item.children ? filterByDepth(item.children) : undefined,
      }))
  }

  return filterByDepth(props.toc)
})

const activeLinks = ref<string[]>([])

onMounted(() => {
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          activeLinks.value.push(entry.target.id)
        }
        else {
          activeLinks.value = activeLinks.value.filter(link => link !== entry.target.id)
        }
      })
    },
    // { rootMargin: '0px 0px -80% 0px' }
  )

  filteredToc.value.forEach((item) => {
    const element = document.getElementById(item.id)
    if (element) {
      observer.observe(element)
    }
    item.children?.forEach((child) => {
      const childElement = document.getElementById(child.id)
      if (childElement) {
        observer.observe(childElement)
      }
    })
  })
})
</script>

<template>
  <ul>
    <template v-for="item in filteredToc" :key="item.id">
      <li>
        <NuxtLink :href="'#' + item.id" class="link" :class="{ active: activeLinks.includes(item.id) }">
          {{ item.text }}
        </NuxtLink>
        <ul v-if="item.children && item.children.length" class="ml-4">
          <template v-for="child in item.children" :key="child.id">
            <li>
              <NuxtLink :href="'#' + child.id" class="link" :class="{ active: activeLinks.includes(child.id) }">
                {{ child.text }}
              </NuxtLink>
            </li>
          </template>
        </ul>
      </li>
    </template>
  </ul>
</template>

<style scoped>
.link {
  @apply text-xs text-neutral-400 dark:text-neutral-500 font-medium;
}

.link.active {
  @apply text-primary;
}
</style>