---
import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
import { render } from 'astro:content';
import config from '@config';
import { AlignLeftIcon } from 'lucide-react';

import mdxComponents from '@components/MDX/components';
import OwnersList from '@components/Lists/OwnersList';

import { getOwner } from '@utils/collections/owners';
import { buildUrl } from '@utils/url-builder';
import { resourceToCollectionMap } from '@utils/collections/util';
import { getMDXComponentsByName } from '@utils/markdown';
import { getAdjacentPages } from '@enterprise/custom-documentation/utils/custom-docs';
import { getCustomDocsContentBadgeClasses } from '@enterprise/custom-documentation/utils/badge-styles';

import CustomDocsNav from '@enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro';
import NodeGraph from '@components/MDX/NodeGraph/NodeGraph.astro';

import { isVisualiserEnabled } from '@utils/feature';

const props = Astro.props;
const doc = props.data;
const { Content, headings } = await render(props as any);
const currentSlug = props.id;

const nodeGraphs = getMDXComponentsByName(props.body, 'NodeGraph') || [];
// Get sidebar data
const sidebar = config?.customDocs?.sidebar || [];

// Flatten the sidebar to find previous and next pages
type FlatItem = {
  label: string;
  slug: string;
};

// Define sidebar section type
type SidebarSection = {
  label: string;
  slug?: string;
  items?: Array<{
    label: string;
    slug: string;
  }>;
};

const flattenedItems: FlatItem[] = [];

// Process all sidebar sections to create a flattened array
sidebar.forEach((section: SidebarSection) => {
  if (section.slug && !section.items) {
    flattenedItems.push({
      label: section.label,
      slug: section.slug,
    });
  }
  if (section.items) {
    section.items.forEach((item: { label: string; slug: string }) => {
      flattenedItems.push({
        label: item.label,
        slug: item.slug,
      });
    });
  }
});

const { prev, next } = await getAdjacentPages(currentSlug);

const ownersRaw = doc?.owners || [];
const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
const filteredOwners = owners.filter((o) => o !== undefined);

const ownersList = filteredOwners.map((o) => ({
  label: o.data.name,
  type: o.collection,
  badge: o.collection === 'users' ? o.data.role : 'Team',
  avatarUrl: o.collection === 'users' ? o.data.avatarUrl : '',
  href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
}));

const badges = doc?.badges || [];

const getCustomDocBadgeClasses = (badge: any) => {
  const color = badge?.backgroundColor || badge?.textColor;
  return `${getCustomDocsContentBadgeClasses(color)} ${badge?.class ? badge.class : ''}`;
};
---

<VerticalSideBarLayout title={doc.title || 'Documentation'} showNestedSideBar={false}>
  <div class="flex w-full" data-pagefind-body data-pagefind-meta={`title:${doc.title}`}>
    <!-- Left Sidebar Navigation -->
    <aside
      class="sidebar-transition overflow-y-auto bg-[rgb(var(--ec-page-bg))] border-r border-[rgb(var(--ec-page-border))] w-80 fixed top-16 bottom-0 z-10"
    >
      <CustomDocsNav />
    </aside>

    <!-- Main Content Area - Independent scrolling -->
    <main
      class="sidebar-transition w-full max-h-content ml-[22em] md:ml-[21em] lg:mr-2 2xl:mr-2 2xl:ml-[22em] pr-2 overflow-y-auto"
    >
      <div class="max-w-none mx-auto px-4 py-10">
        <div class="border-b border-[rgb(var(--ec-page-border))] flex justify-between items-start md:pb-6">
          <div>
            <h2 id="doc-page-header" class="text-2xl md:text-4xl font-bold text-[rgb(var(--ec-page-text))]">{doc.title}</h2>
            <p class="text-lg pt-2 text-[rgb(var(--ec-page-text-muted))] font-light">{doc.summary}</p>
            {
              badges && (
                <div class="flex flex-wrap pt-4">
                  {badges.map((badge: any) => {
                    return (
                      <a href={badge.url || '#'} class="pb-2">
                        <span id={badge.id || ''} class={`${getCustomDocBadgeClasses(badge)} mr-2`}>
                          {badge.icon && <badge.icon className="w-4 h-4 flex-shrink-0 text-[rgb(var(--ec-icon-color))]" />}
                          {badge.iconURL && <img src={badge.iconURL} class="w-4 h-4 flex-shrink-0 opacity-80" alt="" />}
                          <span>{badge.content}</span>
                        </span>
                      </a>
                    );
                  })}
                </div>
              )
            }
          </div>
        </div>
        <div class="flex-auto prose py-8 max-w-none">
          <Content components={{ ...mdxComponents(props) }} />
        </div>

        {
          nodeGraphs.length > 0 &&
            nodeGraphs.map((nodeGraph: any) => {
              const collection = resourceToCollectionMap[nodeGraph.type as keyof typeof resourceToCollectionMap];
              return (
                <NodeGraph
                  id={nodeGraph.id}
                  version={nodeGraph.version}
                  collection={collection}
                  title={nodeGraph.title}
                  mode="simple"
                  linksToVisualiser={true}
                  href={
                    isVisualiserEnabled()
                      ? {
                          label: 'Open in Visualiser',
                          url: buildUrl(`/visualiser/${collection}/${nodeGraph.id}/${nodeGraph.version}`),
                        }
                      : undefined
                  }
                />
              );
            })
        }

        <!-- Previous / Next Navigation -->
        <div class="py-8 border-t border-[rgb(var(--ec-page-border))] mt-8">
          <div class="flex flex-col sm:flex-row justify-between w-full gap-4">
            {
              prev && (
                <a
                  href={buildUrl(`/docs/custom/${prev.slug}`)}
                  class="group flex flex-col border border-[rgb(var(--ec-page-border))] rounded-lg p-4 hover:border-[rgb(var(--ec-content-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] transition-colors w-full sm:w-1/2"
                >
                  <span class="text-sm text-[rgb(var(--ec-page-text-muted))] mb-1">Previous</span>
                  <span class="font-medium text-[rgb(var(--ec-page-text))] group-hover:text-primary-600 transition-colors">
                    {prev.label}
                  </span>
                </a>
              )
            }

            {!prev && <div class="w-full sm:w-1/2" />}

            {
              next && (
                <a
                  href={buildUrl(`/docs/custom/${next.slug}`)}
                  class="group flex flex-col items-end text-right border border-[rgb(var(--ec-page-border))] rounded-lg p-4 hover:border-[rgb(var(--ec-content-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] transition-colors w-full sm:w-1/2"
                >
                  <span class="text-sm text-[rgb(var(--ec-page-text-muted))] mb-1">Next</span>
                  <span class="font-medium text-[rgb(var(--ec-page-text))] group-hover:text-primary-600 transition-colors">
                    {next.label}
                  </span>
                </a>
              )
            }
          </div>
        </div>
      </div>
    </main>

    <!-- Right Sidebar TOC -->
    <aside
      class="hidden lg:block sticky top-0 pb-10 w-80 overflow-y-auto border-l border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg))] p-6 flex-shrink-0 py-2"
    >
      <div class="py-4">
        <div>
          {
            ownersList.length > 0 && (
              <OwnersList
                title={`Document Owners (${ownersList.length})`}
                emptyMessage={`This page does not have any documented owners.`}
                owners={ownersList}
                client:load
              />
            )
          }
        </div>
        <h3 class="text-sm text-[rgb(var(--ec-page-text))] font-semibold capitalize flex items-center gap-2">
          <AlignLeftIcon className="w-4 h-4" />
          On this page
        </h3>
        <nav class="space-y-1 text-sm py-4">
          {
            headings.map((heading) => {
              if (heading.depth > 3) {
                return null;
              }
              return (
                <a
                  href={`#${heading.slug}`}
                  class={`block text-[12px] py-0.5 ${heading.depth === 1 ? 'font-light' : ''} text-[rgb(var(--ec-page-text-muted))] hover:text-primary-600`}
                  style={`padding-left: ${(heading.depth - 1) * 8}px`}
                >
                  {heading.text}
                </a>
              );
            })
          }
        </nav>
      </div>
    </aside>
  </div>
</VerticalSideBarLayout>

<style is:global>
  .mermaid svg {
    margin: 1em auto 2em;
  }

  /* Fix for architecture diagrams */
  .mermaid[data-content*='architecture'] svg {
    max-width: 350px !important;
    margin: 0;
    /* width: 100px !important; */
  }

  /* TOC active state - uses accent CSS variable */
  .toc-active-text {
    color: rgb(var(--ec-accent));
  }
</style>

<script define:vars={{ props, config }}>
  // Fix to pass information to componets that are client side only
  // and require catalog information
  window.eventcatalog = {};
  // @ts-ignore

  window.eventcatalog.mermaid = config.mermaid;
</script>

<script>
  // @ts-nocheck
  function setupObserver() {
    try {
      const observerOptions = {
        rootMargin: '0px 0px -40% 0px',
        threshold: 0.1,
      };

      // Flag to temporarily disable observer after click
      let observerPaused = false;

      // Function to highlight a TOC item
      function highlightTocItem(id: string) {
        // Remove active class from all links
        document.querySelectorAll('.active-toc-item').forEach((link) => {
          link.classList.remove('active-toc-item', 'toc-active-text', 'font-light');
          link.classList.add('text-gray-400');
        });

        // Add active class to current link
        const tocLink = document.querySelector(`nav a[href="#${id}"]`);
        if (tocLink) {
          tocLink.classList.add('active-toc-item', 'toc-active-text', 'font-light');
          tocLink.classList.remove('text-gray-400');

          // Scroll the highlighted item into view with a small delay to ensure DOM updates first
          setTimeout(() => {
            tocLink.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
          }, 10);
        }
      }

      // Set up the intersection observer for scrolling
      const observer = new IntersectionObserver((entries) => {
        // If observer is paused, don't process entries
        if (observerPaused) return;

        entries.forEach((entry) => {
          try {
            const id = entry.target.getAttribute('id');
            if (entry.isIntersecting && id) {
              highlightTocItem(id);
            }
          } catch (entryError) {
            console.error('Error processing intersection entry:', entryError);
          }
        });
      }, observerOptions);

      // Find all headings in the content area within the .prose container to observe
      const prose = document.querySelector('.prose');
      if (!prose) {
        console.warn('No .prose container found for TOC highlighting');
        return;
      }

      // First try to find headings with IDs
      const headings = prose.querySelectorAll('h1[id], h2[id], h3[id]');

      if (headings.length > 0) {
        headings.forEach((heading) => {
          observer.observe(heading);
        });
      } else {
        // Fallback: If no headings with IDs found, attach IDs to them
        const allHeadings = prose.querySelectorAll('h1, h2, h3');

        allHeadings.forEach((heading) => {
          // Only add ID if it doesn't exist
          if (!heading.id) {
            const text = heading.textContent || '';
            const slug = text
              .toLowerCase()
              .replace(/[^\w\s-]/g, '')
              .replace(/\s+/g, '-');
            heading.id = slug;
          }
          observer.observe(heading);
        });
      }

      // Add click event listeners to all TOC links
      const tocLinks = document.querySelectorAll('nav a[href^="#"]');
      tocLinks.forEach((link) => {
        link.addEventListener('click', (e) => {
          // Get the ID from the href attribute
          const hrefAttr = link.getAttribute('href');
          if (!hrefAttr) return;

          const id = hrefAttr.substring(1);

          // Highlight the clicked item
          highlightTocItem(id);

          // Temporarily pause the observer to prevent immediate highlighting changes
          observerPaused = true;

          // Resume the observer after a delay (1.5 seconds)
          setTimeout(() => {
            observerPaused = false;
          }, 500);
        });
      });
    } catch (error) {
      console.error('Error setting up TOC highlighting:', error);
    }
  }

  setupObserver();

  document.addEventListener('astro:page-load', setupObserver);
</script>

<script>
  import { destroyZoomInstances, renderMermaidWithZoom, renderPlantUMLWithZoom } from '@utils/mermaid-zoom';

  function initDiagrams() {
    destroyZoomInstances();

    const mermaidGraphs = document.getElementsByClassName('mermaid');
    if (mermaidGraphs.length > 0) {
      renderMermaidWithZoom(mermaidGraphs, window.eventcatalog?.mermaid);
    }

    const plantumlBlocks = document.getElementsByClassName('plantuml');
    if (plantumlBlocks.length > 0) {
      renderPlantUMLWithZoom(plantumlBlocks);
    }
  }

  // Run on initial load and page transitions
  initDiagrams();
  document.addEventListener('astro:page-load', initDiagrams);

  // Make available globally for accordion component
  window.renderDiagrams = (graphs: HTMLCollectionOf<Element>) => {
    renderMermaidWithZoom(graphs, window.eventcatalog?.mermaid);
  };
  window.renderPlantUML = (blocks: HTMLCollectionOf<Element>) => {
    renderPlantUMLWithZoom(blocks);
  };
</script>
