"use client"

/**
 * SecondaryPanel — nested rail between the primary icon sidebar and content.
 * Full width shows hub scope nav; **compact** matches the primary sidebar icon rail (`w-12`).
 *
 * Chrome uses {@link NestedSecondaryPanelShell}. Library body stays in
 * `library-secondary-nav.tsx` (domain-specific), not duplicated here.
 */

import * as React from "react"
import { useSidebar } from "@/components/ui/sidebar"
import { Tip } from "@/components/ui/tip"
import { Button } from "@/components/ui/button"
import { LibrarySecondaryNav } from "@/components/library-secondary-nav"
import { TokensSecondaryNav } from "@/components/tokens-secondary-nav"
import { NestedSecondaryPanelShell } from "@/components/templates/nested-secondary-panel-shell"
import { useSidebarReflowZoom } from "@/hooks/use-sidebar-reflow-zoom"
import type { LibraryItem } from "@/lib/mock/library"
import type { LibraryFolder } from "@/lib/mock/library-folders"

export type LibraryFolderBridge = {
  folders: LibraryFolder[]
  onFoldersChange: React.Dispatch<React.SetStateAction<LibraryFolder[]>>
  items: LibraryItem[]
  onItemsChange: React.Dispatch<React.SetStateAction<LibraryItem[]>>
}

export type LibraryAccessBridge = {
  openManageAccess: () => void
}

// ─────────────────────────────────────────────────────────────────────────────
// Context
// ─────────────────────────────────────────────────────────────────────────────

export type ClosePanelOptions = {
  /**
   * Main app sidebar after the secondary panel closes.
   * - `restore` (default): snap back to the user's saved preference
   *   (`sidebar_state_v2` cookie, or `defaultOpen` if unset). Use this when
   *   leaving a page whose secondary panel caused an incidental collapse — the
   *   rail returns to the state the user explicitly set elsewhere via ⌘B / the
   *   sidebar button.
   * - `leave`: only clear the active panel — keep the rail in whatever state it
   *   was in (rare; prefer `restore`).
   * - `expand`: force the full primary rail open. Use only when the product
   *   explicitly wants the wide rail after dismiss.
   * - `collapse`: keep the icon rail. Use when the next route also wants compact.
   */
  mainSidebar?: "restore" | "expand" | "collapse" | "leave"
}

interface SecondaryPanelContextValue {
  /** Currently active panel id, or null if none */
  activePanel: string | null
  /** Open a panel by id (always exits compact / full-width). */
  openPanel: (id: string) => void
  /** Close the panel (programmatic / route cleanup). */
  closePanel: (opts?: ClosePanelOptions) => void
  /** Icon-only nested rail while the panel stays “open”. Cleared by {@link openPanel} / {@link closePanel}. */
  secondaryPanelCompact: boolean
  /** Narrow icon rail (primary-sidebar-style); keeps {@link activePanel} mounted. */
  collapseActiveSecondaryPanel: () => void
  /** Library folder tree shared with the secondary nav while the hub is mounted. */
  libraryFolderBridge: LibraryFolderBridge | null
  setLibraryFolderBridge: (bridge: LibraryFolderBridge | null) => void
  /** Opens the hub collaborators sheet from the secondary nav. */
  libraryAccessBridge: LibraryAccessBridge | null
  setLibraryAccessBridge: (bridge: LibraryAccessBridge | null) => void
}

const SecondaryPanelContext = React.createContext<SecondaryPanelContextValue>({
  activePanel: null,
  openPanel: () => {},
  closePanel: () => {},
  secondaryPanelCompact: false,
  collapseActiveSecondaryPanel: () => {},
  libraryFolderBridge: null,
  setLibraryFolderBridge: () => {},
  libraryAccessBridge: null,
  setLibraryAccessBridge: () => {},
})

export function useSecondaryPanel() {
  return React.useContext(SecondaryPanelContext)
}

export function SecondaryPanelProvider({ children }: { children: React.ReactNode }) {
  const [activePanel, setActivePanel] = React.useState<string | null>(null)
  const [secondaryPanelCompact, setSecondaryPanelCompact] = React.useState(false)
  const [libraryFolderBridge, setLibraryFolderBridge] =
    React.useState<LibraryFolderBridge | null>(null)
  const [libraryAccessBridge, setLibraryAccessBridge] =
    React.useState<LibraryAccessBridge | null>(null)
  const { setOpen, restoreSavedOpen } = useSidebar()

  /**
   * Browser zoom ≥ 200% (or very short viewport) — same `useSidebarReflowZoom`
   * signal the primary sidebar uses (WCAG 1.4.10). At that scale the 16rem
   * secondary rail crowds out primary content, so we **auto-collapse it to
   * the icon variant on entering high zoom**. We don't keep overriding —
   * users can re-expand once collapsed; the next zoom-out → zoom-in cycle
   * re-collapses. This matches the pattern users get from clicking the
   * panel's own "Collapse to icons" button.
   */
  const reflowZoom = useSidebarReflowZoom()
  const wasReflowZoomRef = React.useRef(false)
  React.useEffect(() => {
    if (reflowZoom && !wasReflowZoomRef.current) {
      setSecondaryPanelCompact(true)
    }
    wasReflowZoomRef.current = reflowZoom
  }, [reflowZoom])

  const openPanel = React.useCallback(
    (id: string) => {
      // High zoom → keep the icon rail (auto-collapse rule above). At normal
      // zoom this stays the legacy behavior (full-width on open).
      setSecondaryPanelCompact(reflowZoom)
      setActivePanel(id)
      // `persist: false` — collapsing the rail to make room for the secondary
      // panel is an incidental layout side-effect; the user's saved
      // expanded/collapsed preference (cookie) must not be overwritten by it.
      setOpen(false, { persist: false }) // collapse main sidebar to icon rail
    },
    [setOpen, reflowZoom],
  )

  const closePanel = React.useCallback((opts?: ClosePanelOptions) => {
    setSecondaryPanelCompact(false)
    setActivePanel(null)
    /**
     * Default = `restore`. `openPanel` collapsed the rail with `persist: false`
     * (the saved cookie is untouched), so on close we ask the sidebar context
     * to re-apply whatever the user truly saved. This makes the visual collapse
     * scoped to the page that needed it — leave the page → rail comes back to
     * the user's preference.
     */
    const mainSidebar = opts?.mainSidebar ?? "restore"
    if (mainSidebar === "leave") return
    if (mainSidebar === "restore") {
      restoreSavedOpen()
      return
    }
    if (mainSidebar === "collapse") {
      setOpen(false, { persist: false })
      return
    }
    setOpen(true, { persist: false }) // mainSidebar === "expand"
  }, [restoreSavedOpen, setOpen])

  const collapseActiveSecondaryPanel = React.useCallback(() => {
    setSecondaryPanelCompact(true)
  }, [])

  const value = React.useMemo(
    () => ({
      activePanel,
      openPanel,
      closePanel,
      secondaryPanelCompact,
      collapseActiveSecondaryPanel,
      libraryFolderBridge,
      setLibraryFolderBridge,
      libraryAccessBridge,
      setLibraryAccessBridge,
    }),
    [
      activePanel,
      openPanel,
      closePanel,
      secondaryPanelCompact,
      collapseActiveSecondaryPanel,
      libraryFolderBridge,
      libraryAccessBridge,
    ],
  )

  return (
    <SecondaryPanelContext.Provider value={value}>
      {children}
    </SecondaryPanelContext.Provider>
  )
}

// ─────────────────────────────────────────────────────────────────────────────
// SecondaryPanel — the actual rendered panel
// ─────────────────────────────────────────────────────────────────────────────

function LibraryPanel() {
  const { collapseActiveSecondaryPanel, secondaryPanelCompact } = useSecondaryPanel()

  if (secondaryPanelCompact) {
    return <LibrarySecondaryNav />
  }

  return (
    <>
      <div className="flex items-center justify-between gap-2 px-4 pt-4 pb-2">
        <h2
          className="text-xl font-semibold leading-tight text-sidebar-foreground"
          style={{ fontFamily: "var(--font-heading)" }}
        >
          Library
        </h2>
        <Tip label="Collapse to icons" side="bottom">
          <Button
            type="button"
            size="icon"
            variant="ghost"
            onClick={() => collapseActiveSecondaryPanel()}
            aria-label="Collapse to icons"
          >
            <i className="fa-light fa-angles-left" aria-hidden="true" />
          </Button>
        </Tip>
      </div>
      <LibrarySecondaryNav />
    </>
  )
}

function TokensPanel() {
  const { collapseActiveSecondaryPanel, secondaryPanelCompact } = useSecondaryPanel()

  if (secondaryPanelCompact) {
    return <TokensSecondaryNav />
  }

  return (
    <>
      <div className="flex items-center justify-between gap-2 px-4 pt-4 pb-2">
        <h2
          className="text-xl font-semibold leading-tight text-sidebar-foreground"
          style={{ fontFamily: "var(--font-heading)" }}
        >
          Tokens
        </h2>
        <Tip label="Collapse to icons" side="bottom">
          <Button
            type="button"
            size="icon"
            variant="ghost"
            onClick={() => collapseActiveSecondaryPanel()}
            aria-label="Collapse to icons"
          >
            <i className="fa-light fa-angles-left" aria-hidden="true" />
          </Button>
        </Tip>
      </div>
      <TokensSecondaryNav />
    </>
  )
}

/** Register panel components by id when a route opts into `secondaryPanel` in nav. */
const PANELS: Record<string, React.FC> = {
  "library": LibraryPanel,
  tokens: TokensPanel,
}

export function SecondaryPanel() {
  const { activePanel, secondaryPanelCompact } = useSecondaryPanel()
  const PanelContent = activePanel ? PANELS[activePanel] : null

  return (
    <NestedSecondaryPanelShell open={Boolean(activePanel)} compact={secondaryPanelCompact}>
      {PanelContent ? <PanelContent /> : null}
    </NestedSecondaryPanelShell>
  )
}

// ─────────────────────────────────────────────────────────────────────────────
// Auto-open hook — pages call this to show/hide a panel on mount/unmount
// ─────────────────────────────────────────────────────────────────────────────

export function useAutoPanel(panelId: string) {
  const { openPanel, closePanel } = useSecondaryPanel()

  React.useEffect(() => {
    openPanel(panelId)
    return () => {
      closePanel()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [panelId])
}

/** Sync hub folder state into the library secondary nav while the route is mounted. */
export function LibraryFolderBridge({
  folders,
  onFoldersChange,
  items,
  onItemsChange,
}: LibraryFolderBridge) {
  const { setLibraryFolderBridge } = useSecondaryPanel()

  React.useEffect(() => {
    setLibraryFolderBridge({ folders, onFoldersChange, items, onItemsChange })
    return () => setLibraryFolderBridge(null)
  }, [folders, onFoldersChange, items, onItemsChange, setLibraryFolderBridge])

  return null
}

export function LibraryAccessBridge({ openManageAccess }: LibraryAccessBridge) {
  const { setLibraryAccessBridge } = useSecondaryPanel()

  React.useEffect(() => {
    setLibraryAccessBridge({ openManageAccess })
    return () => setLibraryAccessBridge(null)
  }, [openManageAccess, setLibraryAccessBridge])

  return null
}
