'use client'

import * as React from 'react'
import { PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen } from 'lucide-react'
import { cn } from '../../lib/utils'
import { SplitPane } from './SplitPane'

export type WorkspaceLayout = 'split' | 'stack' | 'auto'

export interface DualPaneWorkspaceProps {
  left: React.ReactNode
  right: React.ReactNode
  /** Optional toolbar rendered above both panes (full width). */
  toolbar?: React.ReactNode
  leftLabel?: string
  rightLabel?: string
  /** Initial size of the left pane as a percentage. Default 42. */
  initialLeftSize?: number
  minLeftSize?: number
  maxLeftSize?: number
  /** Persist the split position under this key. */
  storageKey?: string
  /**
   * `split` = resizable side-by-side, `stack` = vertically stacked,
   * `auto` = stack below `stackBreakpoint`, split above. Default `auto`.
   */
  layout?: WorkspaceLayout
  /** Pixel width below which `auto` stacks. Default 768. */
  stackBreakpoint?: number
  /** Show collapse/expand controls for each pane (split layout only). */
  collapsible?: boolean
  className?: string
}

function useResolvedLayout(layout: WorkspaceLayout, stackBreakpoint: number): 'split' | 'stack' {
  const [isNarrow, setIsNarrow] = React.useState(false)
  React.useEffect(() => {
    if (layout !== 'auto' || typeof window === 'undefined') return
    const mql = window.matchMedia(`(max-width: ${stackBreakpoint - 1}px)`)
    const update = () => setIsNarrow(mql.matches)
    update()
    mql.addEventListener?.('change', update)
    return () => mql.removeEventListener?.('change', update)
  }, [layout, stackBreakpoint])

  if (layout === 'split') return 'split'
  if (layout === 'stack') return 'stack'
  return isNarrow ? 'stack' : 'split'
}

interface PaneHeaderProps {
  label?: string
  side: 'left' | 'right'
  collapsible?: boolean
  collapsed: boolean
  onToggle: () => void
}

function PaneHeader({ label, side, collapsible, collapsed, onToggle }: PaneHeaderProps) {
  if (!label && !collapsible) return null
  const CollapseIcon = side === 'left' ? PanelLeftClose : PanelRightClose
  const ExpandIcon = side === 'left' ? PanelLeftOpen : PanelRightOpen
  const Icon = collapsed ? ExpandIcon : CollapseIcon
  const verb = collapsed ? 'Expand' : 'Collapse'
  return (
    <div className="flex h-9 shrink-0 items-center justify-between border-b border-border bg-muted/30 px-3">
      {label ? (
        <span className="text-xs font-medium uppercase tracking-wide text-muted-foreground">{label}</span>
      ) : (
        <span />
      )}
      {collapsible && (
        <button
          type="button"
          onClick={onToggle}
          aria-label={`${verb} ${label ?? side} pane`}
          className="rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
        >
          <Icon className="h-4 w-4" aria-hidden="true" />
        </button>
      )}
    </div>
  )
}

/**
 * Opinionated two-pane workspace shell built on {@link SplitPane}: an optional
 * full-width toolbar, two labelled/collapsible panes side-by-side, and
 * automatic vertical stacking on narrow viewports. Fully app-agnostic — used by
 * present-web for chat | slides, but free of any presentation-specific logic.
 */
export function DualPaneWorkspace({
  left,
  right,
  toolbar,
  leftLabel,
  rightLabel,
  initialLeftSize = 42,
  minLeftSize = 24,
  maxLeftSize = 72,
  storageKey,
  layout = 'auto',
  stackBreakpoint = 768,
  collapsible = false,
  className,
}: DualPaneWorkspaceProps) {
  const resolved = useResolvedLayout(layout, stackBreakpoint)
  const [collapsed, setCollapsed] = React.useState<null | 'left' | 'right'>(null)

  const leftHeader = (
    <PaneHeader
      label={leftLabel}
      side="left"
      collapsible={collapsible}
      collapsed={collapsed === 'left'}
      onToggle={() => setCollapsed((c) => (c === 'left' ? null : 'left'))}
    />
  )
  const rightHeader = (
    <PaneHeader
      label={rightLabel}
      side="right"
      collapsible={collapsible}
      collapsed={collapsed === 'right'}
      onToggle={() => setCollapsed((c) => (c === 'right' ? null : 'right'))}
    />
  )

  const leftPane = (
    <section className="flex h-full min-h-0 flex-col" aria-label={leftLabel}>
      {leftHeader}
      {collapsed !== 'left' && <div className="min-h-0 flex-1 overflow-hidden">{left}</div>}
    </section>
  )
  const rightPane = (
    <section className="flex h-full min-h-0 flex-col" aria-label={rightLabel}>
      {rightHeader}
      {collapsed !== 'right' && <div className="min-h-0 flex-1 overflow-hidden">{right}</div>}
    </section>
  )

  // When one pane is collapsed, the other takes the full width (no resizer).
  let body: React.ReactNode
  if (resolved === 'stack') {
    body = (
      <div className="flex min-h-0 flex-1 flex-col divide-y divide-border" data-layout="stack">
        <div className="min-h-0 flex-1 overflow-hidden">{leftPane}</div>
        <div className="min-h-0 flex-1 overflow-hidden">{rightPane}</div>
      </div>
    )
  } else if (collapsed === 'left') {
    body = (
      <div className="flex min-h-0 flex-1 flex-row" data-layout="split" data-collapsed="left">
        <div className="shrink-0">{leftHeader}</div>
        <div className="min-h-0 flex-1 overflow-hidden">{rightPane}</div>
      </div>
    )
  } else if (collapsed === 'right') {
    body = (
      <div className="flex min-h-0 flex-1 flex-row" data-layout="split" data-collapsed="right">
        <div className="min-h-0 flex-1 overflow-hidden">{leftPane}</div>
        <div className="shrink-0">{rightHeader}</div>
      </div>
    )
  } else {
    body = (
      <div className="min-h-0 flex-1" data-layout="split">
        <SplitPane
          first={leftPane}
          second={rightPane}
          initialSize={initialLeftSize}
          minSize={minLeftSize}
          maxSize={maxLeftSize}
          storageKey={storageKey}
          aria-label="Resize workspace panes"
        />
      </div>
    )
  }

  return (
    <div className={cn('flex h-full min-h-0 w-full flex-col', className)}>
      {toolbar && <div className="shrink-0 border-b border-border">{toolbar}</div>}
      {body}
    </div>
  )
}
