import { clsx } from 'clsx';
import { HTMLAttributes, useContext, useId } from 'react';

import { Position, Typography } from '../common';
import { useLayout } from '../common/hooks';
import Dimmer from '../dimmer';
import { OverlayIdContext } from '../provider/overlay/OverlayIdProvider';
import SlidingPanel from '../slidingPanel';
import Title from '../title';
import { logActionRequiredIf } from '../utilities';
import IconButton from '../iconButton';
import closeBtnMessages from '../common/closeButton/CloseButton.messages';
import { useIntl } from 'react-intl';
import { Cross } from '@transferwise/icons';

export type DrawerProps = {
  /** The content to appear in the drawer body. */
  children?: React.ReactNode;
  className?: string;
  /** The content to appear in the drawer footer. */
  footerContent?: React.ReactNode;
  /** The content to appear in the drawer header. */
  headerTitle?: React.ReactNode;
  /**
   * The status of Drawer either open or not.
   * @default false
   */
  open?: boolean;
  /**
   * The placement of Drawer on the screen either left or right. On mobile it will default to bottom.
   * @default 'right'
   */
  position?: `${Position.LEFT | Position.RIGHT | Position.BOTTOM}`;
  /** The action to perform on close click. */
  onClose?: (event: KeyboardEvent | React.MouseEvent) => void;
  onUnmount?: () => void;
} & Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby'>;

export default function Drawer({
  children,
  className,
  footerContent,
  headerTitle,
  onClose,
  onUnmount,
  open = false,
  position = 'right',
  role = 'dialog',
  'aria-labelledby': ariaLabelledBy,
}: DrawerProps) {
  const intl = useIntl();
  logActionRequiredIf(
    'Drawer now expects `onClose`, and will soon make this prop required. Please update your usage to provide it.',
    !onClose,
  );

  const { isMobile } = useLayout();
  const titleId = useId();

  const overlayId = useContext(OverlayIdContext);

  return (
    <Dimmer open={open} onClose={onClose} onExited={onUnmount}>
      <SlidingPanel open={open} position={isMobile ? Position.BOTTOM : position}>
        <div
          id={overlayId}
          role={role}
          aria-modal
          aria-labelledby={ariaLabelledBy || (headerTitle ? titleId : undefined)}
          className={clsx('np-drawer', className)}
        >
          <div
            className={clsx(
              'np-drawer-header',
              'd-flex',
              'align-items-center',
              headerTitle ? 'justify-content-between' : 'justify-content-end',
              'flex-wrap',
            )}
          >
            {headerTitle && (
              <Title id={titleId} type={Typography.TITLE_SUBSECTION} className="np-drawer-title">
                {headerTitle}
              </Title>
            )}
            <IconButton
              size={40}
              priority="tertiary"
              aria-label={intl.formatMessage(closeBtnMessages.ariaLabel)}
              onClick={onClose}
            >
              <Cross />
            </IconButton>
          </div>
          {children && <div className={clsx('np-drawer-content')}>{children}</div>}
          {footerContent ? (
            <div className={clsx('np-drawer-footer')}>{footerContent}</div>
          ) : (
            <div className="m-t-3" />
          )}
        </div>
      </SlidingPanel>
    </Dimmer>
  );
}
