import { useEffect, useRef, useState } from 'react';
import * as stylex from '@stylexjs/stylex';
import { createPortal } from 'react-dom';

import type { ReactNode } from 'react';

import Box from '~/src/components/Box';
import Clickable from '~/src/components/Clickable';
import CrossIconWrapper from '~/src/components/Icon/CrossIcon';
import useKeyboard from '~/src/hooks/useKeyboard';
import { Text } from '~/src/ui/primitives/text';
import { drawerStyles } from './styles';

interface DrawerProps {
  open: boolean;
  onClose: () => void;
  title?: string;
  children: ReactNode;
}

/**
 * A left-anchored slide-in panel that overlays the viewport, primarily for
 * mobile. Self-managed (no base-ui Dialog) so the slide can be driven purely by
 * StyleX transforms — the panel stays mounted and animates via `open` rather
 * than being toggled with `display: none`. Handles Escape, backdrop dismissal,
 * and body scroll-lock while open.
 */
export const Drawer = ({ open, onClose, title, children }: DrawerProps) => {
  const [mounted, setMounted] = useState(false);
  const panelRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    setMounted(true);
  }, []);

  // Trap Tab focus within the panel, handle Escape, and restore focus to the
  // previously-focused element when the drawer closes. Gated on `open` since
  // the panel stays mounted while closed (see component doc above).
  useKeyboard({
    rootElRef: panelRef,
    active: open,
    onEscape: onClose,
  });

  useEffect(() => {
    if (!open) {
      return;
    }

    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';

    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, [open]);

  if (!mounted) {
    return null;
  }

  return createPortal(
    <div {...stylex.props(drawerStyles.root, !open && drawerStyles.rootClosed)}>
      <div
        {...stylex.props(
          drawerStyles.backdrop,
          open && drawerStyles.backdropOpen
        )}
        aria-hidden="true"
        onClick={onClose}
      />
      <div
        ref={panelRef}
        role="dialog"
        aria-modal="true"
        aria-label={title ?? 'Drawer'}
        {...stylex.props(drawerStyles.panel, open && drawerStyles.panelOpen)}
      >
        <Box flexBox alignCenter>
          {title && (
            <Box flexGrow>
              <Text variant="title-4">{title}</Text>
            </Box>
          )}
          <Box noFlexShrink>
            <Clickable onClick={onClose} title="Close">
              <CrossIconWrapper color="#999999" size={24} />
            </Clickable>
          </Box>
        </Box>
        <div {...stylex.props(drawerStyles.body)}>{children}</div>
      </div>
    </div>,
    document.body
  );
};
