// @design-system: overlays/Drawer
// Registered at /design-system#drawer-overlay - Phase 3 (Agent 3E) will render the gallery.
//
// Bottom sheets use `vaul` (real drag-to-close).
// Side drawers (start/end) use Radix Dialog (focus-trap, Esc-close only — no drag).

import * as RadixDialog from '@radix-ui/react-dialog';
import { Drawer as VaulDrawer } from 'vaul';
import React, { createContext, useContext } from 'react';
import { cn } from '@/lib/cn';

/** Supported drawer slide-in sides */
export type DrawerSide = 'bottom' | 'start' | 'end';

// ─── Internal context — carries side from Root to Content ─────────────────

const DrawerSideContext = createContext<DrawerSide>('bottom');

// ─── Root ─────────────────────────────────────────────────────────────────

/** Props for Drawer root. Extends Radix Dialog root props + side. */
export interface DrawerRootProps extends React.ComponentPropsWithoutRef<typeof RadixDialog.Root> {
  /**
   * Which edge the sheet slides from. Determines the underlying library:
   *   bottom → vaul (real drag-to-close)
   *   start/end → Radix Dialog (focus-trap + Esc only)
   * @default 'bottom'
   */
  side?: DrawerSide;
}

/**
 * Root drawer controller.
 * - side="bottom" → vaul Drawer.Root (drag-to-close).
 * - side="start"|"end" → Radix Dialog.Root.
 */
export function Drawer({ side = 'bottom', children, ...props }: DrawerRootProps) {
  return (
    <DrawerSideContext.Provider value={side}>
      {side === 'bottom' ? (
        <VaulDrawer.Root direction="bottom" {...props}>
          {children}
        </VaulDrawer.Root>
      ) : (
        <RadixDialog.Root {...props}>{children}</RadixDialog.Root>
      )}
    </DrawerSideContext.Provider>
  );
}

/** Trigger element for opening the drawer. Works for both vaul and Radix. */
export const DrawerTrigger = RadixDialog.Trigger;

/** Portal wrapper (internal use — not exported). Works for both vaul and Radix (vaul re-exports Radix Portal). */
const DrawerPortal = RadixDialog.Portal;

// ─── Overlay ──────────────────────────────────────────────────────────────

/** Props for DrawerOverlay (internal use — not exported). */
type DrawerOverlayProps = React.ComponentPropsWithoutRef<typeof RadixDialog.Overlay>;

const overlayBase = 'bg-surface-overlay fixed inset-0 z-[var(--z-overlay)]';

const overlayAnimated = overlayBase + ' motion-overlay-enter motion-overlay-exit';

/** Semi-transparent backdrop (internal use — not exported). */
function DrawerOverlay({ className, ...props }: DrawerOverlayProps) {
  const side = useContext(DrawerSideContext);
  if (side === 'bottom') {
    return (
      <VaulDrawer.Overlay
        data-motion-role="overlay"
        className={cn(overlayBase, className)}
        {...props}
      />
    );
  }
  return (
    <RadixDialog.Overlay
      data-motion-role="overlay"
      className={cn(overlayAnimated, className)}
      {...props}
    />
  );
}

// ─── Content ──────────────────────────────────────────────────────────────

const sideStyles: Record<DrawerSide, string> = {
  bottom: 'inset-x-0 bottom-0 rounded-t-2xl max-h-[90vh]',
  start: 'inset-y-0 start-0 w-80 rounded-e-2xl motion-overlay-panel-enter motion-overlay-panel-exit',
  end: 'inset-y-0 end-0 w-80 rounded-s-2xl motion-overlay-panel-enter motion-overlay-panel-exit',
};

const contentBase =
  'fixed z-[var(--z-modal)] border border-border-default bg-surface-base shadow-xl focus:outline-none overflow-y-auto';

/** Props for DrawerContent */
export interface DrawerContentProps extends React.ComponentPropsWithoutRef<
  typeof RadixDialog.Content
> {
  /**
   * Which edge to slide from.
   * @default inherited from Drawer root side (falls back to 'bottom')
   */
  side?: DrawerSide;
  /** Extra className forwarded to the backdrop overlay. */
  overlayClassName?: string;
}

/** Mobile sheet sliding in from the specified edge. */
export function DrawerContent({
  className,
  children,
  side: sideProp,
  overlayClassName,
  ...props
}: DrawerContentProps) {
  const contextSide = useContext(DrawerSideContext);
  const side = sideProp ?? contextSide;

  if (side === 'bottom') {
    return (
      <VaulDrawer.Portal>
        <DrawerOverlay className={overlayClassName} />
        <VaulDrawer.Content
          data-motion-role="panel"
          className={cn(contentBase, sideStyles.bottom, className)}
          {...props}
        >
          {/* vaul Handle — functional drag target, replaces old decorative div */}
          <VaulDrawer.Handle className="mx-auto mb-4 mt-3 h-1.5 w-10 rounded-full bg-neutral-300" />
          {children}
        </VaulDrawer.Content>
      </VaulDrawer.Portal>
    );
  }

  return (
    <DrawerPortal>
      <DrawerOverlay className={overlayClassName} />
      <RadixDialog.Content
        data-motion-role="panel"
        className={cn(contentBase, sideStyles[side], className)}
        {...props}
      >
        {children}
      </RadixDialog.Content>
    </DrawerPortal>
  );
}

// ─── Sub-components ────────────────────────────────────────────────────────

/** Props for DrawerHeader */
export type DrawerHeaderProps = React.HTMLAttributes<HTMLDivElement>;

/** Header of the drawer. */
export function DrawerHeader({ className, ...props }: DrawerHeaderProps) {
  return <div className={cn('flex flex-col gap-1.5 px-6 pb-4', className)} {...props} />;
}

/** Props for DrawerFooter */
export type DrawerFooterProps = React.HTMLAttributes<HTMLDivElement>;

/** Footer of the drawer. */
export function DrawerFooter({ className, ...props }: DrawerFooterProps) {
  return <div className={cn('mt-auto flex flex-col gap-2 px-6 pb-6 pt-2', className)} {...props} />;
}

/** Props for DrawerTitle */
export type DrawerTitleProps = React.ComponentPropsWithoutRef<typeof RadixDialog.Title>;

/** Drawer title - required for accessibility. */
export function DrawerTitle({ className, ...props }: DrawerTitleProps) {
  return (
    <RadixDialog.Title className={cn('text-lg font-bold text-neutral-900', className)} {...props} />
  );
}

/** Props for DrawerDescription */
export type DrawerDescriptionProps = React.ComponentPropsWithoutRef<typeof RadixDialog.Description>;

/** Drawer description. */
export function DrawerDescription({ className, ...props }: DrawerDescriptionProps) {
  return (
    <RadixDialog.Description className={cn('text-sm text-text-muted', className)} {...props} />
  );
}

/** Props for DrawerClose */
export type DrawerCloseProps = React.ComponentPropsWithoutRef<typeof RadixDialog.Close>;

/** Close button for the drawer. */
export function DrawerClose({ className, ...props }: DrawerCloseProps) {
  return (
    <RadixDialog.Close
      className={cn(
        'absolute end-4 top-4',
        'flex h-8 w-8 items-center justify-center rounded-sm',
        'text-neutral-500 opacity-70',
        'motion-press-feedback transition-opacity hover:opacity-100',
        'focus-visible:ring-brand-primary-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
        className,
      )}
      {...props}
    />
  );
}
