// Copyright 1999-2023. Plesk International GmbH. All rights reserved.

import { disableDocumentScroll, enableDocumentScroll } from '../../utils';
import { isValidElement, useRef, useState, useLayoutEffect, useCallback, useEffect } from 'react';
import { safeInvoke } from '../utils';
import classNames from 'classnames';
import { CLS_PREFIX, Z_INDEX_OVERLAY } from '../../constants';
import Layer from '../Layer';
import FocusTrap from '../FocusTrap';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
/**
 * `Overlay` component.
 */

let overlaysCount = 0;
const OverlayCore = _ref => {
  let {
    baseClassName = `${CLS_PREFIX}overlay`,
    className,
    children = null,
    isOpen: externalIsOpen,
    placement = 'center',
    size = 'md',
    sideBanner,
    sideBannerContainer,
    onClose,
    canCloseOnBackdropClick = true,
    canCloseOnEscapePress = true,
    style = {},
    onAnimationExited,
    ...props
  } = _ref;
  const animationTimeoutRef = useRef();
  const contentRef = useRef(null);
  const prevIsOpen = useRef(externalIsOpen);
  if (prevIsOpen.current !== externalIsOpen) {
    prevIsOpen.current = externalIsOpen;
    if (externalIsOpen) {
      clearTimeout(animationTimeoutRef.current);
    } else {
      animationTimeoutRef.current = window.setTimeout(onAnimationExited, 300);
    }
  }
  useEffect(() => () => clearTimeout(animationTimeoutRef.current), []);
  const [isOpen, setIsOpen] = useState(false);
  useEffect(() => setIsOpen(externalIsOpen), [externalIsOpen]);
  const focus = () => {
    if (contentRef.current === null || document.activeElement === null) {
      return;
    }
    const isFocusOutside = !contentRef.current.contains(document.activeElement);
    if (isFocusOutside) {
      const autofocusElement = contentRef.current.querySelector('[autofocus]');
      if (autofocusElement instanceof HTMLElement) {
        autofocusElement.focus();
      } else {
        contentRef.current.focus();
      }
    }
  };
  useLayoutEffect(() => {
    if (isOpen) focus();
  }, [isOpen]);
  const handleBackdropClick = () => {
    if (canCloseOnBackdropClick) {
      safeInvoke(onClose);
    } else if (isOpen) {
      focus();
    }
  };
  const handleContentKeyUp = e => {
    if (!e.isDefaultPrevented() && e.key === 'Escape') {
      safeInvoke(onClose);
      e.preventDefault();
    }
  };
  const renderImage = sideBanner => {
    const classPrefix = `${baseClassName}__side`;
    let element = null;
    if ( /*#__PURE__*/isValidElement(sideBanner)) {
      element = sideBanner;
    } else if (typeof sideBanner === 'string') {
      element = /*#__PURE__*/_jsx("img", {
        className: `${classPrefix}-image`,
        src: sideBanner,
        alt: ""
      });
    } else {
      element = /*#__PURE__*/_jsx("img", {
        className: `${classPrefix}-image`,
        ...sideBanner
      });
    }
    return /*#__PURE__*/_jsx("div", {
      className: classPrefix,
      children: element
    });
  };
  return /*#__PURE__*/_jsx(Layer, {
    level: Z_INDEX_OVERLAY,
    children: /*#__PURE__*/_jsxs("div", {
      className: classNames(baseClassName, `${baseClassName}--${placement}`, `${baseClassName}--${size}`, sideBanner && `${baseClassName}--side`, isOpen && `${baseClassName}--open`, className),
      style: {
        '--overlay-side-banner-background': sideBannerContainer?.background,
        '--overlay-side-banner-align': sideBannerContainer?.align,
        ...style
      },
      ...props,
      children: [/*#__PURE__*/_jsx("div", {
        className: `${baseClassName}__backdrop`,
        onClick: handleBackdropClick
      }), /*#__PURE__*/_jsxs(FocusTrap, {
        className: `${baseClassName}__content`,
        onKeyUp: canCloseOnEscapePress ? handleContentKeyUp : undefined,
        ref: contentRef,
        role: "dialog",
        "aria-modal": "true",
        children: [/*#__PURE__*/_jsx("div", {
          className: `${baseClassName}__body`,
          children: children
        }), sideBanner && renderImage(sideBanner)]
      })]
    })
  });
};
const Overlay = _ref2 => {
  let {
    isOpen = false,
    ...props
  } = _ref2;
  const isOpenRef = useRef(false);
  const [isExist, setIsExist] = useState(false);
  const prevFocusElementRef = useRef(null);
  const handleClose = useCallback(() => {
    if (!isOpenRef.current) return;
    isOpenRef.current = false;
    if (--overlaysCount === 0) enableDocumentScroll();
    prevFocusElementRef.current?.focus();
  }, []);
  useEffect(() => {
    if (isOpen) {
      isOpenRef.current = true;
      disableDocumentScroll();
      overlaysCount++;
      if (document.activeElement instanceof HTMLElement) {
        prevFocusElementRef.current = document.activeElement;
      }
      setIsExist(true);
    } else {
      handleClose();
    }
  }, [isOpen, handleClose]);
  useEffect(() => () => handleClose(), [handleClose]);
  if (!isExist) return null;
  const handleExited = () => {
    setIsExist(false);
  };
  return /*#__PURE__*/_jsx(OverlayCore, {
    isOpen: isOpen,
    onAnimationExited: handleExited,
    ...props
  });
};
export default Overlay;