import { forwardRef, useMemo } from 'react';

import type { ContainerRef } from '@cleartrip/ct-design-container';
import {
  ActionButtonAlignment,
  ActionButtonVariant,
  Modal,
  ModalWithCloseOverlay,
  type ActionButtonAlignmentType,
  type ActionButtonVariantsType,
} from '@cleartrip/ct-design-modal';

import type { IDialogProps } from './type';

/**
 * Web implementation of `Dialog`.
 *
 * Migrated from aldenui (`core/components/components/Dialog`) per
 * Migration.MD. The yagami Dialog is a thin wrapper around `Modal`
 * that translates the legacy `overlayCloseIcon` flag set into the
 * Modal-level `actionButtonType` + `actionButtonAlignment` contract:
 *
 *   - `isBack`       → `actionButtonType=BACK`, alignment `LEFT`
 *   - `showCloseIcon`→ `actionButtonType=CLOSE`
 *   - `isCenter`     → alignment `CENTER`
 *   - default        → `actionButtonType=NONE`, alignment `RIGHT`
 *
 * The public API surface is preserved 1:1 with aldenui; the only
 * implementation difference on web is that the underlying `Modal`
 * does not yet implement the `actionButton*` slots directly, so we
 * delegate the close-overlay rendering to `ModalWithCloseOverlay`
 * whenever a visible close affordance is requested. The `NONE` case
 * falls through to plain `Modal`.
 */
const Dialog = forwardRef<ContainerRef, IDialogProps>(
  (
    {
      children,
      open,
      variant,
      placement,
      blur,
      allowBackdropClose,
      overlayCloseIcon,
      onClose,
      styleConfig,
      size,
      insidePortal = true,
      actionButtonType: actionButtonTypeFromProps,
      actionButtonAlignment: actionButtonAlignmentFromProps,
    },
    forwardedRef,
  ) => {
    const { root: customRootStyles = [], modalWrapperStyles = [] } = styleConfig || {};
    const {
      show = false,
      isBack = false,
      showCloseIcon = false,
      isCenter = false,
      isTop = true,
    } = overlayCloseIcon || {};

    // Translate legacy `overlayCloseIcon` flags to the new
    // Modal-level `actionButton*` contract. Explicit `actionButton*`
    // props take precedence so consumers can opt into the new API
    // directly without touching `overlayCloseIcon`.
    const actionButtonAlignment = useMemo<ActionButtonAlignmentType>(() => {
      if (actionButtonAlignmentFromProps) return actionButtonAlignmentFromProps;
      if (isBack) return ActionButtonAlignment.LEFT;
      if (isCenter) return ActionButtonAlignment.CENTER;
      return ActionButtonAlignment.RIGHT;
    }, [actionButtonAlignmentFromProps, isBack, isCenter]);

    const actionButtonType = useMemo<ActionButtonVariantsType>(() => {
      if (actionButtonTypeFromProps) return actionButtonTypeFromProps;
      if (isBack) return ActionButtonVariant.BACK;
      if (showCloseIcon || show) return ActionButtonVariant.CLOSE;
      return ActionButtonVariant.NONE;
    }, [actionButtonTypeFromProps, isBack, showCloseIcon, show]);

    const needsOverlay = actionButtonType !== ActionButtonVariant.NONE;

    if (needsOverlay) {
      return (
        // `ModalWithCloseOverlay` expects an `HTMLDivElement` ref while
        // the public Dialog ref signature is `ContainerRef` for
        // cross-platform parity with native. The cast keeps the public
        // type stable until web Modal adopts the new ref shape.
        <ModalWithCloseOverlay
          ref={forwardedRef}
          variant={variant}
          placement={placement}
          allowBackdropClose={allowBackdropClose}
          onClose={onClose}
          blur={blur}
          open={open}
          insidePortal={insidePortal}
          size={size}
          isBack={actionButtonType === ActionButtonVariant.BACK}
          isCenter={actionButtonAlignment === ActionButtonAlignment.CENTER}
          isTop={isTop}
          styleConfig={{ root: customRootStyles, modalContentStyles: modalWrapperStyles }}
        >
          {children}
        </ModalWithCloseOverlay>
      );
    }

    return (
      <Modal
        ref={forwardedRef}
        variant={variant}
        placement={placement}
        allowBackdropClose={allowBackdropClose}
        onClose={onClose}
        blur={blur}
        open={open}
        insidePortal={insidePortal}
        size={size}
        styleConfig={{
          root: customRootStyles,
          modalContentStyles: modalWrapperStyles,
        }}
      >
        {children}
      </Modal>
    );
  },
);

Dialog.displayName = 'Dialog';

export default Dialog;
