import type { ReactNode } from 'react'
import { cn } from '@/lib/cn'

/**
 * The editor's side rail, and the answer to "four things want one rail".
 *
 * The inspector, history, journal, and (later) the chat panel all want the same
 * strip of screen. Rather than each bolting on its own chrome, they are tabs in
 * one rail — which keeps the canvas one width instead of a different
 * width per panel, and means adding the journal or chat is adding a tab.
 *
 * Two constraints shaped it:
 *
 *   - Selecting an object must land you in the inspector with no extra click.
 *     The editor watches the selection and switches to that tab itself, so the
 *     rail never becomes a thing you have to operate before you can edit.
 *   - The canvas has to stay worth watching while the agent edits it, so the
 *     rail is a fixed 20rem column and closes completely when nothing needs it.
 *
 * On a phone the same tabs render in a bottom sheet, which is where the
 * inspector already lived.
 */

export interface RailTab {
  id: string
  label: string
  /** Rendered lazily: only the active tab's content is built. */
  render: () => ReactNode
  /** Shown as a dot on the tab — a count, or true for a plain marker. */
  badge?: number | boolean
}

export function EditorRail({
  tabs,
  activeId,
  onActivate,
  onClose,
}: {
  tabs: RailTab[]
  activeId: string
  onActivate: (id: string) => void
  onClose: () => void
}) {
  const active = tabs.find((t) => t.id === activeId) ?? tabs[0]
  if (!active) return null

  return (
    <div
      className={cn(
        // Phone: an in-flow PEEK — a capped-height panel that sits between the
        // canvas and the always-visible mode bar (the editor's flex column places
        // it there), so the garden stays visible above it and the mode bar stays
        // reachable below. The canvas flexes to fill whatever's left. Desktop: a
        // fixed-width column beside the canvas.
        'flex max-h-[50vh] min-h-0 shrink-0 flex-col rounded-t-xl border-t border-border bg-surface shadow-lg',
        'md:static md:max-h-none md:w-80 md:rounded-xl md:border md:shadow-sm',
      )}
    >
      <div className="flex items-center gap-1 border-b border-border px-2 py-1.5">
        {tabs.map((tab) => (
          <button
            key={tab.id}
            type="button"
            onClick={() => onActivate(tab.id)}
            aria-current={tab.id === active.id ? 'page' : undefined}
            className={cn(
              'flex items-center gap-1.5 rounded-md px-2.5 py-1 text-sm font-medium outline-none transition-colors',
              'focus-visible:ring-2 focus-visible:ring-accent/40',
              tab.id === active.id ? 'bg-border/60 text-fg' : 'text-muted hover:text-fg',
            )}
          >
            {tab.label}
            {tab.badge != null && tab.badge !== false && tab.badge !== 0 && (
              <span className="rounded-full bg-accent/20 px-1.5 text-[10px] font-semibold text-accent-strong">
                {tab.badge === true ? '•' : tab.badge}
              </span>
            )}
          </button>
        ))}
        <button
          type="button"
          onClick={onClose}
          aria-label="Close panel"
          className="ml-auto rounded px-1.5 text-sm text-muted outline-none hover:text-fg focus-visible:ring-2 focus-visible:ring-accent/40"
        >
          ✕
        </button>
      </div>
      <div className="min-h-0 flex-1 overflow-y-auto p-4">{active.render()}</div>
    </div>
  )
}
