---
// Table of Contents Component - Extracts headings from article content
import { getI18n } from '../lib/i18n';

const { t } = getI18n(Astro);
const hasBeforeNav = Astro.slots.has('before-nav');
---

<aside
  id="toc-container"
  class="hidden w-full shrink-0 xl:block xl:w-[17.5rem] 2xl:w-[18.5rem]"
  data-has-before-nav={hasBeforeNav ? 'true' : 'false'}
>
  <div class="sticky top-28 space-y-4">
    <slot name="before-nav" />

    <div
      id="toc-panel"
      class="rounded-[24px] border border-[var(--border-color)]/72 bg-[linear-gradient(180deg,rgba(255,255,255,0.96),rgba(250,252,255,0.92))] p-4 shadow-[0_14px_34px_rgba(15,23,42,0.055)] backdrop-blur"
    >
      <div class="space-y-4">
        <span class="terminal-kicker w-fit">
          <i class="fas fa-terminal"></i>
          nav stack
        </span>

        <div class="space-y-1.5 border-b border-[var(--border-color)]/62 pb-3">
          <h3 class="text-[1.02rem] font-semibold tracking-[0.01em] text-[var(--title-color)]">
            {t('toc.title')}
          </h3>
          <p class="text-[12.5px] leading-6 text-[var(--text-secondary)]">
            {t('toc.intro')}
          </p>
        </div>

        <nav
          id="toc-nav"
          class="max-h-[calc(100vh-260px)] overflow-y-auto pr-1"
          aria-label={t('toc.title')}
        >
          <!-- TOC items will be generated by JavaScript -->
        </nav>
      </div>
    </div>
  </div>
</aside>

<style is:inline>
  #toc-nav {
    position: relative;
    display: grid;
    gap: 0.2rem;
    padding-left: 0.1rem;
    overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: color-mix(in oklab, var(--primary) 24%, transparent) transparent;
  }

  #toc-nav::before {
    content: '';
    position: absolute;
    left: 0.46rem;
    top: 0.5rem;
    bottom: 0.5rem;
    width: 1px;
    background: linear-gradient(
      180deg,
      color-mix(in oklab, var(--border-color) 78%, transparent),
      color-mix(in oklab, var(--primary) 10%, transparent)
    );
    pointer-events: none;
  }

  #toc-nav::-webkit-scrollbar {
    width: 6px;
  }

  #toc-nav::-webkit-scrollbar-thumb {
    border-radius: 999px;
    background: color-mix(in oklab, var(--primary) 24%, transparent);
  }

  #toc-nav .toc-link {
    box-sizing: border-box;
    position: relative;
    display: grid;
    grid-template-columns: 0.7rem minmax(0, 1fr);
    align-items: start;
    gap: 0.7rem;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    border-radius: 0.9rem;
    border: 0;
    background: transparent;
    padding: 0.56rem 0.72rem 0.56rem 0.18rem;
    color: var(--text-secondary);
    transition:
      background-color 160ms ease,
      color 160ms ease,
      transform 160ms ease,
      box-shadow 160ms ease;
  }

  #toc-nav .toc-link:hover {
    background: color-mix(in oklab, var(--primary) 4%, var(--terminal-bg));
    color: var(--title-color);
  }

  #toc-nav .toc-link.is-active {
    background: color-mix(in oklab, var(--primary) 7%, var(--terminal-bg));
    color: var(--primary);
    box-shadow:
      inset 2px 0 0 var(--primary),
      0 0 0 1px color-mix(in oklab, var(--primary) 10%, transparent);
  }

  #toc-nav .toc-link-sub {
    margin-left: 0.85rem;
    padding-top: 0.45rem;
    padding-bottom: 0.45rem;
    color: var(--text-secondary);
  }

  #toc-nav .toc-link-dot {
    position: relative;
    z-index: 1;
    display: inline-block;
    width: 0.52rem;
    height: 0.52rem;
    margin-top: 0.42rem;
    border-radius: 999px;
    background: color-mix(in oklab, var(--border-color) 82%, white 18%);
    box-shadow: 0 0 0 6px color-mix(in oklab, var(--card-bg, white) 92%, transparent);
    transition:
      background-color 160ms ease,
      transform 160ms ease,
      box-shadow 160ms ease;
  }

  #toc-nav .toc-link:hover .toc-link-dot {
    background: color-mix(in oklab, var(--primary) 32%, var(--border-color));
  }

  #toc-nav .toc-link.is-active .toc-link-dot {
    background: var(--primary);
    transform: scale(1.05);
    box-shadow: 0 0 0 6px color-mix(in oklab, var(--primary) 10%, white 90%);
  }

  #toc-nav .toc-link-sub .toc-link-dot {
    width: 0.38rem;
    height: 0.38rem;
    margin-top: 0.5rem;
    margin-left: 0.08rem;
    background: color-mix(in oklab, var(--text-tertiary) 60%, var(--border-color));
  }

  #toc-nav .toc-link-label {
    min-width: 0;
    flex: 1;
    text-align: left;
    line-height: 1.5;
    word-break: break-word;
    font-size: 0.9rem;
    font-weight: 500;
    letter-spacing: 0.01em;
  }

  #toc-nav .toc-link-sub .toc-link-label {
    font-size: 0.82rem;
    color: color-mix(in oklab, var(--text-secondary) 88%, var(--text-tertiary));
    font-weight: 450;
  }

  #toc-nav .toc-link-sub.is-active .toc-link-label {
    color: var(--primary);
  }
</style>

<script is:inline>
  (function() {
    function generateTOC() {
      const content = document.querySelector('.article-content');
      if (!content) return;

      const headings = content.querySelectorAll('h2, h3');
      const tocNav = document.getElementById('toc-nav');
      const tocPanel = document.getElementById('toc-panel');
      const container = document.getElementById('toc-container');
      const hasBeforeNav = container?.getAttribute('data-has-before-nav') === 'true';

      if (!tocNav || headings.length === 0) {
        if (tocPanel) tocPanel.style.display = 'none';
        if (container && !hasBeforeNav) container.style.display = 'none';
        return;
      }

      tocNav.innerHTML = '';
      headings.forEach((heading, index) => {
        if (!heading.id) {
          heading.id = `heading-${index}`;
        }

        const link = document.createElement('a');
        link.href = `#${heading.id}`;
        link.className = heading.tagName === 'H3' ? 'toc-link toc-link-sub' : 'toc-link';
        link.innerHTML = `
          <span class="toc-link-dot" aria-hidden="true"></span>
          <span class="toc-link-label">${heading.textContent || ''}</span>
        `;

        link.addEventListener('click', (e) => {
          e.preventDefault();
          heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
        });

        tocNav.appendChild(link);
      });

      const observer = new IntersectionObserver(
        (entries) => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              const links = tocNav.querySelectorAll('a');
              links.forEach(link => {
                link.classList.remove('is-active');
                link.removeAttribute('aria-current');
                if (link.getAttribute('href') === `#${entry.target.id}`) {
                  link.classList.add('is-active');
                  link.setAttribute('aria-current', 'true');
                }
              });
            }
          });
        },
        { rootMargin: '-20% 0px -75% 0px' }
      );

      headings.forEach(heading => observer.observe(heading));
    }

    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', generateTOC);
    } else {
      generateTOC();
    }
  })();
</script>
