import { relative, basename, extname } from 'path';
import { resolvePagePath, loadPageContent } from '../config';
import { extractFrontmatter, safeParseFrontmatter } from '../mdx';
/**
 * Navigation Generator
 * 
 * Builds navigation structure from docs.json configuration
 */ /**
 * Generate navigation from configuration
 */ export function generateNavigation(config, docsDir) {
    const nav = config.navigation;
    const navigation = {};
    // Handle tabbed navigation
    if (nav.tabs && nav.tabs.length > 0) {
        navigation.tabs = nav.tabs.map((tab)=>buildNavTab(tab, docsDir));
    }
    // Handle single-page navigation (no tabs)
    if (nav.groups && nav.groups.length > 0) {
        navigation.groups = nav.groups.map((group)=>buildNavGroup(group, docsDir));
    }
    // Add global anchors
    if (nav.global?.anchors) {
        navigation.anchors = nav.global.anchors.map((anchor)=>({
                title: anchor.anchor,
                href: anchor.href,
                icon: anchor.icon,
                external: anchor.href.startsWith('http')
            }));
    }
    return navigation;
}
/**
 * Build a navigation tab
 */ function buildNavTab(tab, docsDir) {
    const slug = tab.tab.toLowerCase().replace(/\s+/g, '-');
    // Only docs tabs have groups
    if ('groups' in tab && tab.groups) {
        const groups = tab.groups.map((group)=>buildNavGroup(group, docsDir));
        return {
            title: tab.tab,
            slug,
            groups
        };
    }
    // For openapi/changelog tabs, return empty groups
    return {
        title: tab.tab,
        slug,
        groups: []
    };
}
/**
 * Build a navigation group
 */ function buildNavGroup(group, docsDir) {
    const items = group.pages.map((page)=>buildNavItemOrGroup(page, docsDir)).filter((item)=>item !== null);
    return {
        title: group.group,
        icon: group.icon,
        items,
        collapsible: true,
        defaultCollapsed: false
    };
}
/**
 * Build a navigation item or nested group from a page reference
 */ function buildNavItemOrGroup(pageRef, docsDir) {
    // Handle nested groups
    if (typeof pageRef === 'object' && 'group' in pageRef) {
        const nestedItems = pageRef.pages.map((p)=>buildNavItemOrGroup(p, docsDir)).filter((item)=>item !== null);
        return {
            title: pageRef.group,
            items: nestedItems,
            collapsible: true,
            defaultCollapsed: false
        };
    }
    return buildNavItem(pageRef, docsDir);
}
/**
 * Build a navigation item from a page reference
 */ function buildNavItem(pageRef, docsDir) {
    // Check if it's an external link
    if (pageRef.startsWith('http://') || pageRef.startsWith('https://')) {
        return {
            title: pageRef,
            href: pageRef,
            external: true
        };
    }
    // Resolve the page file
    const filePath = resolvePagePath(docsDir, pageRef);
    if (!filePath) {
        console.warn(`Page not found: ${pageRef}`);
        return {
            title: pageRef,
            href: `/${pageRef}`
        };
    }
    // Load and parse frontmatter
    try {
        const content = loadPageContent(filePath);
        const { data } = extractFrontmatter(content);
        const frontmatter = safeParseFrontmatter(data);
        // Build URL path
        const urlPath = pageRef === 'index' ? '/' : `/${pageRef}`;
        return {
            title: frontmatter?.sidebarTitle || frontmatter?.title || pageRef,
            href: urlPath,
            icon: frontmatter?.icon,
            deprecated: frontmatter?.deprecated
        };
    } catch (error) {
        console.warn(`Failed to load page metadata: ${pageRef}`, error);
        return {
            title: pageRef,
            href: `/${pageRef}`
        };
    }
}
/**
 * Helper to check if an item is a NavItem (has href)
 */ function isNavItem(item) {
    return 'href' in item && typeof item.href === 'string';
}
/**
 * Recursively collect all NavItems from items array (handles nested groups)
 */ function collectNavItems(items) {
    const result = [];
    for (const item of items){
        if (isNavItem(item)) {
            result.push(item);
        } else if ('items' in item && Array.isArray(item.items)) {
            result.push(...collectNavItems(item.items));
        }
    }
    return result;
}
/**
 * Find navigation context for a specific page
 */ export function findPageNavContext(navigation, currentPath) {
    const breadcrumbs = [];
    let prev;
    let next;
    let currentTab;
    let currentGroup;
    let currentItem;
    // Normalize path
    const normalizedPath = currentPath.startsWith('/') ? currentPath : `/${currentPath}`;
    // Flatten all items for prev/next calculation
    const allItems = [];
    // Search in tabs
    if (navigation.tabs) {
        for (const tab of navigation.tabs){
            for (const group of tab.groups){
                const groupItems = collectNavItems(group.items);
                allItems.push(...groupItems);
                for (const item of groupItems){
                    if (item.href === normalizedPath) {
                        currentTab = tab;
                        currentGroup = group;
                        currentItem = item;
                        // Build breadcrumbs
                        breadcrumbs.push({
                            title: tab.title,
                            href: `/${tab.slug}`
                        });
                        breadcrumbs.push({
                            title: group.title,
                            href: '#'
                        });
                        breadcrumbs.push({
                            title: item.title,
                            href: item.href
                        });
                    }
                }
            }
        }
    }
    // Search in groups (non-tabbed)
    if (navigation.groups) {
        for (const group of navigation.groups){
            const groupItems = collectNavItems(group.items);
            allItems.push(...groupItems);
            for (const item of groupItems){
                if (item.href === normalizedPath) {
                    currentGroup = group;
                    currentItem = item;
                    // Build breadcrumbs
                    breadcrumbs.push({
                        title: group.title,
                        href: '#'
                    });
                    breadcrumbs.push({
                        title: item.title,
                        href: item.href
                    });
                }
            }
        }
    }
    // Find prev/next
    const currentIndex = allItems.findIndex((item)=>item.href === normalizedPath);
    if (currentIndex > 0) {
        prev = allItems[currentIndex - 1];
    }
    if (currentIndex >= 0 && currentIndex < allItems.length - 1) {
        next = allItems[currentIndex + 1];
    }
    return {
        breadcrumbs,
        prev,
        next,
        currentTab,
        currentGroup,
        currentItem
    };
}
/**
 * Get all page paths from navigation
 */ export function getAllPagePaths(navigation) {
    const paths = [];
    if (navigation.tabs) {
        for (const tab of navigation.tabs){
            for (const group of tab.groups){
                const items = collectNavItems(group.items);
                for (const item of items){
                    if (!item.external) {
                        paths.push(item.href);
                    }
                }
            }
        }
    }
    if (navigation.groups) {
        for (const group of navigation.groups){
            const items = collectNavItems(group.items);
            for (const item of items){
                if (!item.external) {
                    paths.push(item.href);
                }
            }
        }
    }
    return paths;
}
/**
 * Load page metadata from file
 */ export function loadPageMeta(filePath, docsDir) {
    try {
        const content = loadPageContent(filePath);
        const { data } = extractFrontmatter(content);
        const frontmatter = safeParseFrontmatter(data);
        // Calculate URL path from file path
        const relativePath = relative(docsDir, filePath);
        const urlPath = '/' + relativePath.replace(/\.(mdx?|md)$/, '').replace(/\/index$/, '').replace(/^index$/, '');
        return {
            filePath: relativePath,
            urlPath: urlPath || '/',
            title: frontmatter?.title || basename(filePath, extname(filePath)),
            description: frontmatter?.description,
            sidebarTitle: frontmatter?.sidebarTitle,
            icon: frontmatter?.icon,
            hidden: frontmatter?.hidden
        };
    } catch  {
        return null;
    }
}
