/* The side panel — one wrapper, many contents.
 *
 * The way a Gutenberg inspector hosts different settings in one frame, this
 * hosts whatever the app needs beside the work: a discussion, a table of
 * contents, settings. It owns the frame (header, optional tabs, scrolling
 * body, pinned footer, close, Escape); the app owns what goes in it.
 *
 * Docked over the right edge with NO backdrop by default, so the work stays
 * interactive beside it — a person reads a note and looks at the design at
 * the same time. `modal` adds a scrim for the flows that genuinely need one. */

import { useEffect, type ReactNode } from "react";

export type PanelTab = { key: string; label: string; count?: number };

export function SidePanel({
  open, onClose, eyebrow, title, subtitle, tabs, activeTab, onTab,
  footer, children, modal = false, back, ariaLabel,
}: {
  open: boolean;
  onClose: () => void;
  eyebrow?: string;
  title?: ReactNode;
  subtitle?: ReactNode;
  tabs?: PanelTab[];
  activeTab?: string;
  onTab?: (key: string) => void;
  /** Pinned below the scrolling body — a composer lives here. */
  footer?: ReactNode;
  children?: ReactNode;
  modal?: boolean;
  /** A "‹ Back" affordance above the title, for drill-in views. */
  back?: { label: string; onClick: () => void };
  ariaLabel?: string;
}) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  if (!open) return null;

  return (
    <>
      {modal && (
        <button type="button" className="cu-panel-scrim" aria-label="Close"
                onClick={onClose} />
      )}
      <aside className="cu-panel" role={modal ? "dialog" : "complementary"}
             aria-modal={modal || undefined}
             aria-label={ariaLabel ?? (typeof title === "string" ? title : eyebrow)}>
        <header className="cu-panel-head">
          <div className="cu-panel-title-row">
            <div>
              {back && (
                <button type="button" className="cu-panel-back" onClick={back.onClick}>
                  <span aria-hidden="true">‹</span> {back.label}
                </button>
              )}
              {eyebrow && <span className="cu-panel-eyebrow">{eyebrow}</span>}
              {title && <h2 className="cu-panel-title">{title}</h2>}
              {subtitle && <p className="cu-panel-sub">{subtitle}</p>}
            </div>
            <button type="button" className="cu-panel-close" aria-label="Close panel"
                    onClick={onClose}>×</button>
          </div>
          {tabs && tabs.length > 0 && (
            <div className="cu-panel-tabs" role="tablist">
              {tabs.map((t) => (
                <button key={t.key} type="button" role="tab"
                        aria-selected={t.key === activeTab}
                        className={`cu-panel-tab ${t.key === activeTab ? "is-on" : ""}`}
                        onClick={() => onTab?.(t.key)}>
                  {t.label}
                  {typeof t.count === "number" && t.count > 0 && (
                    <span className="cu-panel-tab-count">{t.count}</span>
                  )}
                </button>
              ))}
            </div>
          )}
        </header>
        <div className="cu-panel-body">{children}</div>
        {footer && <footer className="cu-panel-foot">{footer}</footer>}
      </aside>
    </>
  );
}

export function PanelEmpty({ children }: { children: ReactNode }) {
  return <p className="cu-panel-empty">{children}</p>;
}
