/**
 * Navigation helper utilities for SDK sites.
 *
 * Provides helpers to transform CMS navigation data into render-ready structures.
 * All navigation functions return nested structures supporting dropdowns.
 *
 * @example Getting nav items
 * ```ts
 * import { getPrimaryNavItems, isNavLink, isNavDropdown } from '@riverbankcms/sdk/navigation';
 *
 * const headerNav = getPrimaryNavItems(siteData.navigation, {
 *   routes: siteData.routes,
 *   pagesByIdentifier: siteData.pagesByIdentifier,
 *   entriesByIdentifier: siteData.entriesByIdentifier,
 * });
 * headerNav.forEach(item => {
 *   if (isNavLink(item)) {
 *     console.log(item.href);
 *   } else {
 *     console.log(`${item.label} has ${item.children.length} children`);
 *   }
 * });
 * ```
 *
 * @example Building menu and logo
 * ```ts
 * import { buildMenu, buildLogo } from '@riverbankcms/sdk/navigation';
 *
 * const menu = buildMenu(siteData.navigation, siteData.routes, {
 *   pagesByIdentifier: siteData.pagesByIdentifier,
 *   entriesByIdentifier: siteData.entriesByIdentifier,
 * });
 * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
 * ```
 *
 * @packageDocumentation
 */
import type { LinkPayload, NavigationMenuWithItems } from '../public-api/contracts';
import type { LinkValue, RouteMap } from '../contracts';
export type { InternalLinkValue, ExternalLinkValue, CustomLinkValue, PageLinkValue, EntryLinkValue, LinkValue, } from '../contracts';
export type NavigationRenderOptions = {
    /** Route map used by item helpers that don't receive routes directly (for `page`/`entry` href resolution). */
    routes?: RouteMap;
    /** Whether the current request has a portal session cookie. */
    hasPortalSession?: boolean;
    /** Render stage controls internal link eligibility/resolution. Defaults to published. */
    previewStage?: 'preview' | 'published';
    /** Page identifier -> routeId lookup used to resolve `{ kind: 'page' }` links. */
    pagesByIdentifier?: Record<string, string>;
    /** Entry identifier lookups used to resolve `{ kind: 'entry' }` links. */
    entriesByIdentifier?: Record<string, Record<string, string>>;
    /**
     * Whether portal links should render for this site.
     * When false, portal links are omitted as a fail-safe.
     */
    portalEnabled?: boolean;
    /**
     * Whether cart links should render for this site.
     * When false, cart links are omitted as a fail-safe.
     */
    commerceEnabled?: boolean;
    /**
     * Dedicated checkout route href for cart navigation items.
     * Defaults to `/checkout` when omitted.
     */
    checkoutHref?: string | null;
};
export type CartNavViewModel = Readonly<{
    visibleLabel: string | null;
    badge: 'show-count' | 'hidden';
    ariaLabel: string;
    checkoutHref: string | null;
}>;
/**
 * Menu link view model for block rendering
 */
export type MenuLinkViewModel = {
    id: string;
    label: string;
    link: LinkValue | null;
    target: string | null;
    rel: string | null;
    active?: boolean;
    cart?: CartNavViewModel;
    /** Optional nested children for dropdown menus (1 level deep). */
    children?: MenuLinkViewModel[];
};
/**
 * CTA link view model (extends MenuLinkViewModel with variant)
 */
export type MenuCtaViewModel = MenuLinkViewModel & {
    variant: string;
};
/**
 * Complete menu view model for header/footer blocks
 */
export type MenuViewModel = {
    items: MenuLinkViewModel[];
    ctaItem: MenuCtaViewModel | null;
};
/**
 * Logo source data from site layout
 */
export type LogoSource = {
    url: string | null;
    alt: string | null;
    assetId?: string | null;
    width?: number | null;
    height?: number | null;
    storagePath?: string | null;
    storageBucket?: string | null;
} | null;
/**
 * Logo view model for block rendering
 */
export type LogoViewModel = {
    type: 'image';
    src: string;
    alt: string;
    assetId?: string;
    width?: number | null;
    height?: number | null;
    storagePath?: string;
    storageBucket?: string;
} | null;
/**
 * A navigation link item with a direct URL.
 * Use `kind` discriminator for type-safe narrowing.
 *
 * @example
 * ```ts
 * if (item.kind === 'link') {
 *   console.log(item.href);  // TypeScript knows href exists
 * }
 * ```
 */
export type NavLink = {
    /** Discriminator for type narrowing */
    kind: 'link';
    /** Unique identifier from CMS */
    id: string;
    /** Display text for the navigation link */
    label: string;
    /** The URL to navigate to */
    href: string;
    /** Link object for block rendering (used by navRow's links.resolve transform) */
    link: {
        href: string;
    };
    /** Whether link should open in new tab (external links) */
    isExternal: boolean;
    /** Optional cart metadata for cart-aware renderers. */
    cart?: CartNavViewModel;
};
/**
 * A dropdown container holding child navigation items.
 * Clicking reveals children instead of navigating.
 * Max 1 level of nesting (children are always NavLink, not NavDropdown).
 */
export type NavDropdown = {
    /** Discriminator for type narrowing */
    kind: 'dropdown';
    /** Unique identifier from CMS */
    id: string;
    /** Display text for the dropdown trigger */
    label: string;
    /** Child navigation links */
    children: NavLink[];
};
/**
 * Navigation item - either a link or a dropdown container.
 * Use `kind` property for type-safe discrimination.
 *
 * @example
 * ```ts
 * const items = getPrimaryNavItems(navigation);
 * items.forEach(item => {
 *   if (item.kind === 'link') {
 *     console.log(item.href);
 *   } else {
 *     console.log(item.children.length);
 *   }
 * });
 * ```
 */
export type NavItem = NavLink | NavDropdown;
/**
 * Type guard to check if a navigation item is a link.
 */
export declare function isNavLink(item: NavItem): item is NavLink;
/**
 * Type guard to check if a navigation item is a dropdown.
 */
export declare function isNavDropdown(item: NavItem): item is NavDropdown;
/**
 * Navigation menu with items and optional CTA.
 * Built from CMS navigation data with pre-resolved hrefs.
 *
 * @example
 * ```ts
 * const menu = buildMenu(siteData.navigation, siteData.routes);
 * menu.items.forEach(item => {
 *   if (item.kind === 'link') {
 *     console.log(item.href);
 *   } else {
 *     console.log(item.children);
 *   }
 * });
 * ```
 */
export type Menu = {
    items: NavItem[];
    ctaItem: (NavLink & {
        variant: string;
    }) | null;
    /**
     * Convenience arrays derived from `items`.
     * Primarily used for footer rendering:
     * - `groups`: dropdown items (with `children`)
     * - `links`: root link items (no `children`)
     */
    groups?: NavDropdown[];
    links?: NavLink[];
};
/**
 * Footer menu view model with convenience partitions always populated.
 */
export type FooterMenu = Omit<Menu, 'ctaItem' | 'groups' | 'links'> & {
    ctaItem: null;
    groups: NavDropdown[];
    links: NavLink[];
};
/**
 * Logo data for site rendering.
 *
 * @example
 * ```ts
 * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
 * if (logo) {
 *   <img src={logo.src} alt={logo.alt} />
 * }
 * ```
 */
export type Logo = {
    type: 'image';
    src: string;
    alt: string;
    width?: number;
    height?: number;
} | null;
/** @deprecated Use `NavLink` instead */
export type SimpleNavLink = NavLink;
/** @deprecated Use `NavDropdown` instead */
export type SimpleNavDropdown = NavDropdown;
/** @deprecated Use `NavItem` instead */
export type SimpleNavItem = NavItem;
/** @deprecated Use `Menu` instead */
export type SimpleMenuViewModel = Menu;
/** @deprecated Use `Logo` instead */
export type SimpleLogo = Logo;
/**
 * Get the primary navigation menu object.
 * Returns menu marked as isPrimary, or first menu if none marked.
 *
 * @example
 * ```ts
 * const menu = getPrimaryNavigation(siteData.navigation);
 * console.log(menu?.name); // "main"
 * ```
 */
export declare function getPrimaryNavigation(navigation: NavigationMenuWithItems[] | null | undefined): NavigationMenuWithItems | null;
/**
 * Get the footer navigation menu object.
 * Returns menu marked as isFooter, or null if none marked.
 *
 * @example
 * ```ts
 * const menu = getFooterNavigation(siteData.navigation);
 * console.log(menu?.name); // "Footer menu"
 * ```
 */
export declare function getFooterNavigation(navigation: NavigationMenuWithItems[] | null | undefined): NavigationMenuWithItems | null;
/**
 * Get a navigation menu by name/slug.
 *
 * @example
 * ```ts
 * const footerMenu = getNavigationBySlug(siteData.navigation, 'footer');
 * ```
 */
export declare function getNavigationBySlug(navigation: NavigationMenuWithItems[] | null | undefined, slug: string): NavigationMenuWithItems | null;
/**
 * Get nav items from the primary menu (marked isPrimary, or first menu).
 * Returns nested structure supporting both links and dropdowns.
 * For canonical links (`kind: 'page' | 'entry'`), pass `routes` + identifier maps in options.
 *
 * @example
 * ```ts
 * const headerNav = getPrimaryNavItems(siteData.navigation, {
 *   routes: siteData.routes,
 *   pagesByIdentifier: siteData.pagesByIdentifier,
 *   entriesByIdentifier: siteData.entriesByIdentifier,
 * });
 * headerNav.forEach(item => {
 *   if (item.kind === 'dropdown') {
 *     console.log(`${item.label} has ${item.children.length} children`);
 *   }
 * });
 * ```
 */
export declare function getPrimaryNavItems(navigation: NavigationMenuWithItems[], options?: NavigationRenderOptions): NavItem[];
/**
 * Get nav items from a specific menu by slug.
 * Returns nested structure supporting both links and dropdowns.
 * For canonical links (`kind: 'page' | 'entry'`), pass `routes` + identifier maps in options.
 *
 * @example
 * ```ts
 * const footerNav = getNavItemsBySlug(siteData.navigation, 'footer', {
 *   routes: siteData.routes,
 *   pagesByIdentifier: siteData.pagesByIdentifier,
 *   entriesByIdentifier: siteData.entriesByIdentifier,
 * });
 * ```
 */
export declare function getNavItemsBySlug(navigation: NavigationMenuWithItems[], slug: string, options?: NavigationRenderOptions): NavItem[];
/**
 * Transform a menu into NavItem array.
 * Builds nested structure from flat items, supporting dropdowns with children.
 *
 * @example
 * ```ts
 * const nav = transformToNavItems(menu, {
 *   routes: siteData.routes,
 *   pagesByIdentifier: siteData.pagesByIdentifier,
 *   entriesByIdentifier: siteData.entriesByIdentifier,
 * });
 * // [
 * //   { kind: 'link', href: '/', label: 'Home', ... },
 * //   { kind: 'dropdown', label: 'Services', children: [...] },
 * // ]
 * ```
 */
export declare function transformToNavItems(menu: NavigationMenuWithItems | null, options?: NavigationRenderOptions): NavItem[];
/**
 * Build a MenuViewModel from navigation data for block rendering.
 * Extracts CTA item separately and preserves full link data.
 *
 * @example
 * ```ts
 * const menuViewModel = buildMenuViewModel(siteData.navigation);
 *
 * renderBlock(siteHeaderManifest, layout.header, {
 *   viewModelOverrides: { menu: menuViewModel },
 * });
 * ```
 */
export declare function buildMenuViewModel(navigation: NavigationMenuWithItems[], options?: NavigationRenderOptions): MenuViewModel;
/**
 * Build a LogoViewModel from site layout data.
 *
 * @param logo - Logo source from siteData.layout.logo
 * @param fallbackTitle - Site title to use as alt text fallback
 *
 * @example
 * ```ts
 * const logoViewModel = buildLogoViewModel(siteData.layout.logo, siteData.site.title);
 *
 * renderBlock(siteHeaderManifest, layout.header, {
 *   viewModelOverrides: { content: { logo: logoViewModel } },
 * });
 * ```
 */
export declare function buildLogoViewModel(logo: LogoSource, fallbackTitle: string | null | undefined): LogoViewModel;
/**
 * Build a Menu from navigation data with pre-resolved hrefs.
 * Supports dropdown containers with nested children.
 *
 * @param navigation - Navigation menus from site data
 * @param routes - Route map for resolving internal links
 * @param options - Include identifier maps to resolve canonical `page`/`entry` links.
 *
 * @example
 * ```ts
 * const menu = buildMenu(siteData.navigation, siteData.routes, {
 *   pagesByIdentifier: siteData.pagesByIdentifier,
 *   entriesByIdentifier: siteData.entriesByIdentifier,
 * });
 * menu.items.forEach(item => {
 *   if (item.kind === 'dropdown') {
 *     console.log(item.children);
 *   }
 * });
 * ```
 */
export declare function buildMenu(navigation: NavigationMenuWithItems[], routes: RouteMap, options?: NavigationRenderOptions): Menu;
/**
 * Build a Menu from the footer navigation data.
 * Returns empty menu if no footer menu is designated.
 *
 * @param navigation - Navigation menus from site data
 * @param routes - Route map for resolving internal links
 * @param options - Include identifier maps to resolve canonical `page`/`entry` links.
 *
 * @example
 * ```ts
 * const footerMenu = buildFooterMenu(siteData.navigation, siteData.routes, {
 *   pagesByIdentifier: siteData.pagesByIdentifier,
 *   entriesByIdentifier: siteData.entriesByIdentifier,
 * });
 * footerMenu.items.forEach(item => {
 *   if (item.kind === 'dropdown') {
 *     // Footer renders children expanded, not as hover dropdowns
 *     console.log(item.children);
 *   }
 * });
 * ```
 */
export declare function buildFooterMenu(navigation: NavigationMenuWithItems[], routes: RouteMap, options?: NavigationRenderOptions): FooterMenu;
export declare function resolveNavigationLinkHref(link: LinkPayload | null, routes: RouteMap, options?: NavigationRenderOptions): string | null;
/**
 * Build a Logo from site layout data.
 *
 * @param logo - Logo data from site layout
 * @param fallbackAlt - Fallback alt text (usually site title)
 *
 * @example
 * ```ts
 * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
 * // { src: 'https://...', alt: 'Site Name', width: 200, height: 50 }
 * ```
 */
export declare function buildLogo(logo: Partial<LogoSource> | null, fallbackAlt: string | null | undefined): Logo;
export type { NavigationMenuWithItems, NavigationItemRecord, LinkPayload } from '../public-api/contracts';
