// DocShell composition — sidebar + main grid for documentation.
// Sidebar nav is data-driven (group → entry tree); apps pass their
// own structure. Sticky sidebar, scrollable main, responsive collapse
// to single-column under 800px.
//
// `LinkComponent` lets the app inject a client-side router (e.g.
// `Link` from `@voltro/web`) so sidebar nav doesn't trigger full
// page reloads. Default is plain `<a>` so the kit stays
// router-agnostic and works in any host.

import type { ComponentType, ReactNode } from 'react'
import { cn } from '../cn'

export interface DocNavEntry {
  readonly label: string
  readonly href: string
}

export interface DocNavGroup {
  readonly section: string
  readonly entries: ReadonlyArray<DocNavEntry>
}

// Minimal Link prop surface — matches @voltro/web's Link with `to`,
// and degrades cleanly to a plain <a href> when not provided.
export interface ShellLinkProps {
  readonly to: string
  readonly className?: string
  readonly children: ReactNode
  /** Pre-warm the destination on hover/focus. */
  readonly prefetch?: boolean
}

interface DocShellProps {
  readonly brand: ReactNode
  readonly nav: ReadonlyArray<DocNavGroup>
  readonly children: ReactNode
  readonly currentPath?: string
  readonly className?: string
  /** Search form GET action. When set, renders a search input that
   *  POSTs ?q=… to this URL. */
  readonly searchAction?: string
  /** Placeholder for the search input. Default `'Search docs…'`. */
  readonly searchPlaceholder?: string
  /** `aria-label` for the search input. Default `'Search docs'`. */
  readonly searchLabel?: string
  /** Optional client-router Link. Passing `Link` from `@voltro/web`
   *  upgrades every sidebar entry to client-side navigation with
   *  loader prefetch. */
  readonly LinkComponent?: ComponentType<ShellLinkProps>
}

const PlainLink = ({ to, className, children }: ShellLinkProps): ReactNode => (
  <a href={to} className={className}>{children}</a>
)

export const DocShell = ({
  brand, nav, children, currentPath, className, searchAction,
  searchPlaceholder = 'Search docs…', searchLabel = 'Search docs',
  LinkComponent = PlainLink,
}: DocShellProps): ReactNode => {
  const Link = LinkComponent
  return (
    <div className={cn('min-h-screen grid grid-cols-1 md:grid-cols-[260px_1fr] bg-background text-foreground', className)}>
      <aside className="border-r bg-card/30 p-6 md:sticky md:top-0 md:h-screen md:overflow-y-auto">
        <div className="mb-6">{brand}</div>
        {searchAction ? (
          <form method="get" action={searchAction} className="mb-6">
            <input
              type="search"
              name="q"
              placeholder={searchPlaceholder}
              aria-label={searchLabel}
              className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-ring"
            />
          </form>
        ) : null}
        {nav.map((group) => (
          <div key={group.section} className="mb-6">
            <h4 className="text-xs uppercase tracking-wider text-muted-foreground font-medium mb-2">
              {group.section}
            </h4>
            <ul className="space-y-0.5">
              {group.entries.map((e) => {
                const active = currentPath === e.href
                return (
                  <li key={e.href}>
                    <Link
                      to={e.href}
                      prefetch
                      className={cn(
                        'block rounded-md px-2 py-1.5 text-sm transition-colors',
                        active
                          ? 'bg-accent text-accent-foreground font-medium'
                          : 'text-muted-foreground hover:bg-accent/50 hover:text-foreground',
                      )}
                    >
                      {e.label}
                    </Link>
                  </li>
                )
              })}
            </ul>
          </div>
        ))}
      </aside>
      <main className="p-8 md:p-12 lg:p-16 max-w-3xl text-foreground">
        {children}
      </main>
    </div>
  )
}
