import { useEffect, useState } from 'react'
import type { ReactNode } from 'react'

export interface AdminShellProps {
  /** Sidebar/navigation slot. Rendered in the left column on desktop. */
  sidebar: ReactNode
  /** Top header slot. Rendered above the main content. */
  header?: ReactNode
  /** Optional breadcrumb / sub-header slot rendered below the header. */
  breadcrumbs?: ReactNode
  /** Main content. Scrolls independently of the sidebar. */
  children: ReactNode
  /**
   * Whether the mobile sidebar overlay is currently open. Controlled.
   * AdminShell renders the backdrop + slide transform; the consumer owns
   * the open state and the hamburger button that toggles it.
   */
  mobileSidebarOpen?: boolean
  onMobileSidebarClose?: () => void
  /**
   * Breakpoint above which the sidebar docks beside the content instead
   * of overlaying on top of it. Mirrors Tailwind's `md` (768px) default.
   */
  desktopBreakpoint?: number
}

/**
 * The canonical admin chrome. Owns the entire viewport, splits into
 * `sidebar | (header + breadcrumbs + content)`, and handles the mobile
 * overlay transition.
 *
 * Implementation notes:
 *  - Desktop layout is CSS Grid with `gridTemplateColumns: 'auto minmax(0, 1fr)'`.
 *    The `minmax(0, 1fr)` is load-bearing: it lets the content shrink
 *    below its intrinsic width when the sidebar takes its share, which
 *    is the one thing flex-based shells fail at.
 *  - Mobile layout is a single block with the sidebar absolutely
 *    positioned and slid in via `transform: translateX(…)`. We avoid
 *    the brittle `fixed` ↔ `static` toggle that caused recurring sidebar
 *    overlap bugs in the old layout.
 *  - The desktop/mobile decision is made in JS via `matchMedia` so the
 *    layout is independent of Tailwind's `md:` utility compilation. If
 *    the CSS bundle is stale or partially loaded the layout still works.
 */
export function AdminShell({
  sidebar,
  header,
  breadcrumbs,
  children,
  mobileSidebarOpen = false,
  onMobileSidebarClose,
  desktopBreakpoint = 768,
}: AdminShellProps) {
  const [isDesktop, setIsDesktop] = useState(false)

  useEffect(() => {
    if (typeof window === 'undefined') return
    const mq = window.matchMedia(`(min-width: ${desktopBreakpoint}px)`)
    const handler = () => setIsDesktop(mq.matches)
    handler()
    mq.addEventListener('change', handler)
    return () => mq.removeEventListener('change', handler)
  }, [desktopBreakpoint])

  return (
    <div
      className="bg-background text-foreground h-screen overflow-hidden"
      style={
        isDesktop
          ? { display: 'grid', gridTemplateColumns: 'auto minmax(0, 1fr)' }
          : { display: 'block', position: 'relative' }
      }
    >
      {!isDesktop && mobileSidebarOpen && (
        <div
          aria-hidden
          className="fixed inset-0 z-40 bg-black/30 backdrop-blur-sm"
          onClick={onMobileSidebarClose}
        />
      )}

      <div
        className="z-50"
        style={
          isDesktop
            ? {
                gridColumn: '1 / 2',
                height: '100vh',
                overflow: 'hidden',
              }
            : {
                position: 'fixed',
                top: 0,
                bottom: 0,
                left: 0,
                transform: mobileSidebarOpen ? 'translateX(0)' : 'translateX(-100%)',
                transition: 'transform 300ms ease',
              }
        }
      >
        {sidebar}
      </div>

      <div
        className="flex flex-col overflow-hidden"
        style={
          isDesktop
            ? { gridColumn: '2 / 3', height: '100vh', minWidth: 0 }
            : { height: '100vh', minWidth: 0 }
        }
      >
        {header}
        {breadcrumbs}
        <main className="flex-1 overflow-y-auto">{children}</main>
      </div>
    </div>
  )
}
