<template>
  <div class="chapter-toc" ref="tocRoot">
    <button class="toc-toggle" @click="open = !open" :aria-expanded="open">
      <div class="i-lucide-list h-4 w-4" />
      <span>Sommaire</span>
      <div class="i-lucide-chevron-down h-3.5 w-3.5 toc-chevron" :class="{ 'toc-chevron--open': open }" />
    </button>

    <Transition name="toc-dropdown">
      <div v-if="open" class="toc-panel">
        <nav>
          <a
            v-for="item in headings"
            :key="item.id"
            :href="`#${item.id}`"
            class="toc-item"
            :class="{ 'toc-item--h2': item.level === 2 }"
            @click="open = false"
          >
            {{ item.text }}
          </a>
        </nav>
      </div>
    </Transition>
  </div>
</template>

<script setup lang="ts">
interface TocHeading {
  id: string
  text: string
  level: number
}

const open = ref(false)
const headings = ref<TocHeading[]>([])
const tocRoot = ref<HTMLElement>()

function extractHeadings() {
  const article = document.querySelector('.prose-lyrics')
  if (!article) return

  const nodes = article.querySelectorAll('h1, h2')
  headings.value = Array.from(nodes)
    .filter(el => el.id)
    .map(el => ({
      id: el.id,
      text: el.textContent?.trim() ?? '',
      level: parseInt(el.tagName[1]),
    }))
}

// Close on click outside
function onClickOutside(e: MouseEvent) {
  if (tocRoot.value && !tocRoot.value.contains(e.target as Node)) {
    open.value = false
  }
}

onMounted(() => {
  // Wait for content to render
  nextTick(() => {
    extractHeadings()
    // Retry after a short delay in case content loads async
    setTimeout(extractHeadings, 500)
  })
  document.addEventListener('click', onClickOutside)
})

onUnmounted(() => {
  document.removeEventListener('click', onClickOutside)
})
</script>

<style scoped>
.chapter-toc {
  position: relative;
  display: inline-block;
}

.toc-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  border-radius: 0.375rem;
  background: hsl(20 8% 10%);
  border: 1px solid hsl(20 8% 18%);
  color: hsl(20 8% 60%);
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.toc-toggle:hover {
  border-color: hsl(20 8% 30%);
  color: white;
}

.toc-chevron {
  transition: transform 0.2s;
}

.toc-chevron--open {
  transform: rotate(180deg);
}

.toc-panel {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  z-index: 30;
  min-width: 280px;
  max-width: 400px;
  max-height: 60vh;
  overflow-y: auto;
  padding: 0.5rem;
  border-radius: 0.5rem;
  background: hsl(20 8% 8%);
  border: 1px solid hsl(20 8% 16%);
  box-shadow: 0 8px 32px hsl(0 0% 0% / 0.4);
}

.toc-item {
  display: block;
  padding: 0.5rem 0.75rem;
  border-radius: 0.375rem;
  font-size: 0.8rem;
  color: hsl(20 8% 65%);
  text-decoration: none;
  transition: all 0.15s;
  line-height: 1.3;
}

.toc-item:hover {
  background: hsl(20 8% 12%);
  color: white;
}

.toc-item--h2 {
  padding-left: 1.5rem;
  font-size: 0.75rem;
  color: hsl(20 8% 50%);
}

/* Dropdown transition */
.toc-dropdown-enter-active {
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.toc-dropdown-leave-active {
  transition: all 0.15s ease-in;
}
.toc-dropdown-enter-from,
.toc-dropdown-leave-to {
  opacity: 0;
  transform: translateY(-4px);
}
</style>
