import { type ReactNode } from 'react';

import DesignSystemDrawer from '@design-system/Drawer';

import { useLayerStack } from '../common/useLayerStack';

import {
  DrawerLayerContext,
  useDrawerLayer,
  useDrawerLayerItem,
} from './hooks';
import {
  type DrawerCloseReason,
  type OpenDrawerArgs,
  type SimpleDrawerProps,
} from './types';
import { getDrawerSize, isCompositionDrawer } from './utils';

export { useDrawerLayer, useDrawerLayerItem };

/**
 * Context provider for managing drawers globally.
 *
 * Manages a stack of drawers that can be opened from anywhere in the app.
 * Supports Simple API (props-based) and Composition Components API (custom layouts).
 *
 * @see README.md for full documentation and examples
 */
export function DrawerLayerProvider({ children }: { children: ReactNode }) {
  const {
    stack,
    open: openDrawer,
    close: closeDrawer,
    handleTransitionEnd,
    getStack: getDrawers,
    updateConfig: updateDrawerConfig,
  } = useLayerStack<OpenDrawerArgs>({
    prepareConfig: (config, _id, closeById) => ({
      onClose: closeById,
      ...config,
    }),
  });

  return (
    <DrawerLayerContext.Provider
      value={{
        openDrawer,
        closeDrawer,
        getDrawers,
        updateDrawerConfig,
      }}
    >
      {children}

      {stack.map((level, index) => {
        const isLast = index === stack.length - 1;
        const config = level.config;

        const handleClose = (reason?: DrawerCloseReason) => {
          level.config.onClose?.(reason);
        };

        const simpleConfig = isCompositionDrawer(config)
          ? undefined
          : (config as SimpleDrawerProps);

        return (
          <DesignSystemDrawer.Wrapper
            key={level.id}
            open={level.isOpen}
            disableEscapeKeyDown={false}
            onClose={
              isLast
                ? reason => {
                    handleClose(reason);
                  }
                : undefined
            }
            size={getDrawerSize(config)}
            enableTaskFocus={simpleConfig?.enableTaskFocus}
            SlideProps={{
              ...config.wrapperProps?.SlideProps,
              onExited: () => handleTransitionEnd(level.id),
            }}
            {...config.wrapperProps}
          >
            {isCompositionDrawer(level.config) ? (
              level.config.content
            ) : (
              <DesignSystemDrawer.Content
                {...(level.config as SimpleDrawerProps)}
                onClose={handleClose}
              />
            )}
          </DesignSystemDrawer.Wrapper>
        );
      })}
    </DrawerLayerContext.Provider>
  );
}

/**
 * Re-export Drawer composition components from design-system
 */
export const Drawer = {
  Header: DesignSystemDrawer.Header,
  Body: DesignSystemDrawer.Body,
  DoubleLayout: DesignSystemDrawer.DoubleLayout,
  Footer: DesignSystemDrawer.Footer,
  Actions: DesignSystemDrawer.Actions,
  Content: DesignSystemDrawer.Content,
};
