'use client'

import { useMemo, useState, useEffect, type ReactNode } from 'react'
import { Plus } from 'lucide-react'
import { Sidebar } from './Sidebar.js'
import { Header } from './Header.js'
import { Breadcrumbs } from '../components/Breadcrumbs.js'
import { AdminShell } from './primitives/AdminShell.js'
import { Toaster } from 'sonner'

export interface LayoutProps {
  config: any
  session: any
  currentPath: string
  onNavigate: (path: string) => void
  onLogout?: () => void
  children: ReactNode
}

/**
 * Layout — thin shell that wires Sidebar/Header/Breadcrumbs into the
 * `<AdminShell>` primitive.
 *
 * `AdminShell` (in `./primitives/AdminShell.tsx`) owns the actual layout
 * algorithm (CSS Grid on desktop, fixed slide-in overlay on mobile,
 * JS-driven `matchMedia` breakpoint) so that every layout decision lives
 * in one place. Per-product chrome (Sidebar, Header, Breadcrumbs)
 * composes on top of it.
 *
 * DO NOT re-implement layout logic in this file — extend `AdminShell`
 * instead. The previous flex + `fixed`↔`static` toggle caused recurring
 * sidebar-overlap bugs; the grid-based primitive is the contract.
 */
export function Layout({
  config,
  session,
  currentPath,
  onNavigate,
  onLogout,
  children,
}: LayoutProps) {
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false)

  useEffect(() => {
    setMobileSidebarOpen(false)
  }, [currentPath])

  const pageActions = useMemo(
    () => computePageActions({ currentPath, config, onNavigate }),
    [currentPath, config, onNavigate],
  )

  return (
    <>
      <Toaster position="bottom-right" />
      <AdminShell
        mobileSidebarOpen={mobileSidebarOpen}
        onMobileSidebarClose={() => setMobileSidebarOpen(false)}
        sidebar={
          <Sidebar
            collapsed={sidebarCollapsed}
            onToggleCollapse={() => setSidebarCollapsed(!sidebarCollapsed)}
            currentPath={currentPath}
            onNavigate={onNavigate}
            config={config}
          />
        }
        header={
          <Header
            onToggleSidebar={() => setMobileSidebarOpen(!mobileSidebarOpen)}
            session={session}
            onNavigate={onNavigate}
            onLogout={onLogout}
            pageActions={pageActions}
          />
        }
        breadcrumbs={<Breadcrumbs currentPath={currentPath} onNavigate={onNavigate} />}
      >
        <div className="h-full">{children}</div>
      </AdminShell>
    </>
  )
}

// ─── Page actions ────────────────────────────────────────────────────────────

interface PageActionsContext {
  currentPath: string
  config: any
  onNavigate: (path: string) => void
}

/**
 * Per-route primary actions that render on the right of the top bar.
 *
 * Centralised here so the top bar's actions row stays consistent
 * across view changes — no flicker on navigation, no per-view header
 * reimplementation. Views that need view-local actions (e.g. a
 * "Save draft" button on the post editor) continue to render them
 * inside their own hero; this slot is for the highest-level
 * primary/secondary pair that mirrors the reference dashboard.
 *
 * Resolution rules:
 *   - Dashboard / Posts / Pages → nothing here; those views render their
 *     hero CTAs inside the page header per the design
 *   - Other list views → just "+ New <Type>"
 *   - Editor views → no top-bar action (editor renders its own toolbar)
 */
function computePageActions({
  currentPath,
  config,
  onNavigate,
}: PageActionsContext): ReactNode | null {
  const collections = collectionList(config)

  // Dashboard, /posts, and /pages render their own hero CTAs in the page
  // header (design `.page-hdr` → `.hdr-r`), so the top bar stays empty there.
  const isDashboard = currentPath === '/' || currentPath === '/dashboard'
  if (isDashboard || currentPath === '/posts' || currentPath === '/pages') {
    return null
  }

  if (currentPath === '/posts/types') {
    return (
      <button
        type="button"
        onClick={() => onNavigate('/posts/types/new')}
        className="bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-lg px-3.5 py-1.5 text-sm font-medium shadow-sm transition-colors focus:outline-none focus-visible:ring-2"
      >
        <Plus className="h-3.5 w-3.5" aria-hidden />
        New Post Type
      </button>
    )
  }

  // List views — surface "+ New X" so authors can keep creating without
  // hunting for a per-list button. Skip on editor views; those have their
  // own toolbar.
  for (const c of collections) {
    if (currentPath === `/${c.slug}`) {
      return (
        <button
          type="button"
          onClick={() => onNavigate(`/${c.slug}/new`)}
          className="bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-lg px-3.5 py-1.5 text-sm font-medium shadow-sm transition-colors focus:outline-none focus-visible:ring-2"
        >
          <Plus className="h-3.5 w-3.5" aria-hidden />
          New {c.labels?.singular ?? c.slug}
        </button>
      )
    }
  }

  return null
}

interface CollectionMeta {
  slug: string
  type?: string
  labels?: { singular?: string; plural?: string }
  admin?: { hidden?: boolean }
}

function collectionList(config: any): CollectionMeta[] {
  if (!config?.collections) return []
  const raw = config.collections
  const list: any[] = Array.isArray(raw) ? raw : Object.values(raw)
  return list.filter((c) => !c?.admin?.hidden)
}
