import { useEffect, useRef, useId } from 'react';
import styles from './index.module.scss';
import cx from '../utils/classname.js';
import { DrawerProps } from './types.js';
import { useFocusTrap } from './hooks/useFocusTrap.js';
import { drawerStack, isTopmostDrawer } from './drawerStack.js';

const Drawer = ({
  open,
  direction = 'right',
  variant = 'primary',
  className = '',
  style = {},
  children,
  showOverlay = true,
  onOverlayClick = () => {},
  fullScreen = false,
  size = '300px',
  zIndex,
  overlayZIndex,
  'aria-label': ariaLabel,
  'aria-labelledby': ariaLabelledby,
  ...rest
}: DrawerProps) => {
  const drawerRef = useRef<HTMLDivElement>(null);
  const drawerId = useId();
  const isInStackRef = useRef(false);

  const removeDrawerFromStack = () => {
    const index = drawerStack.indexOf(drawerId);
    if (index > -1) {
      drawerStack.splice(index, 1);
    }
    isInStackRef.current = false;
    // Only remove class if no drawers remain
    if (drawerStack.length === 0) {
      document.body.classList.remove('drawerOpen');
    }
  };

  useEffect(() => {
    // Add this drawer to the stack when it opens (if not already added)
    if (open && !isInStackRef.current) {
      drawerStack.push(drawerId);
      isInStackRef.current = true;
      document.body.classList.add('drawerOpen');
    } else if (!open && isInStackRef.current) {
      removeDrawerFromStack();
    }

    if (!open) {
      return;
    }

    // Only close the topmost drawer when Escape is pressed
    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape' && isTopmostDrawer(drawerStack, drawerId)) {
        onOverlayClick();
      }
    };

    document.addEventListener('keydown', handleEscape);

    return () => {
      document.removeEventListener('keydown', handleEscape);
    };
  }, [open, onOverlayClick, drawerId]);

  // Cleanup: ensure drawer is removed from stack on unmount
  useEffect(() => {
    return () => {
      if (isInStackRef.current) {
        removeDrawerFromStack();
      }
    };
  }, [drawerId]);

  useFocusTrap({
    containerRef: drawerRef,
    active: open,
    drawerId,
    drawerStack,
  });

  const directionClass = styles[direction];
  const openClass = open ? styles.open : '';
  const fullScreenClass = fullScreen ? styles.fullScreen : '';

  const defaultClasses = cx(
    styles.drawer,
    directionClass,
    openClass,
    fullScreenClass
  );
  const combinedClasses = cx(defaultClasses, className);

  const sizeStyle: React.CSSProperties = fullScreen
    ? {}
    : direction === 'left' || direction === 'right'
    ? { width: size }
    : { height: size };

  const drawerStyle: React.CSSProperties = {
    ...sizeStyle,
    ...(zIndex != null ? { zIndex } : {}),
    ...style,
  };

  return (
    <>
      {showOverlay && open && (
        <div
          className={styles.overlay}
          onClick={onOverlayClick}
          aria-hidden="true"
          style={overlayZIndex != null ? { zIndex: overlayZIndex } : undefined}
        />
      )}
      <div
        ref={drawerRef}
        className={combinedClasses}
        style={drawerStyle}
        role="dialog"
        aria-modal="true"
        aria-hidden={!open}
        aria-label={ariaLabel}
        aria-labelledby={ariaLabelledby}
        tabIndex={-1}
        {...rest}
      >
        {children}
      </div>
    </>
  );
};

export default Drawer;
export { useDrawer } from './hooks/index.js';
