import ReactDOM from 'react-dom';
import React, { useLayoutEffect, useRef } from 'react';
import classnames from 'classnames';
import { createPopper } from '@popperjs/core';
import { faGripVertical } from '@fortawesome/free-solid-svg-icons/faGripVertical';
import { OFFSET_MODIFIER } from '../react-popper';
import { useTranslation } from '../hooks';
import { FloatingPanelContext, resizeHandles, getHtmlElement } from './constants';
import { useFloatingPanelState } from './use-floating-panel-state';
import { DraggableArea } from './draggable-area';
import { FloatingPanelHeader } from './floating-panel-header';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const noop = () => false;

/**
 * Floating panel
 * @midnight-gray-supported
 * @uxr-only-supported
 * @alpine-light-supported
 */
export function FloatingPanel({
  children,
  minHeight = 648,
  minWidth = 380,
  maxWidth = 900,
  maxHeight = 800,
  anchorEl,
  dockEl,
  pageContentEl,
  initialState,
  testId = 'floating-panel',
  placement = 'bottom',
  popperModifiers = [OFFSET_MODIFIER],
  onClose = noop,
  actions,
  dragIcon = faGripVertical,
  ...props
}) {
  const containerElement = getHtmlElement(dockEl) || document.getElementById('floating-panel-root') || document.body;
  const initialStateAppliedOnce = useRef(false);
  const {
    t
  } = useTranslation();
  const {
    panelRef,
    headerRef,
    style,
    onResize,
    onMovementStart,
    onResizeEnd,
    setPosition,
    isDocked,
    isCollapsed,
    setIsDocked,
    getPosition,
    context
  } = useFloatingPanelState({
    minHeight,
    minWidth,
    maxWidth,
    maxHeight,
    initialState,
    isDocked: props.isDocked ?? false,
    setIsDocked: props.setIsDocked ?? noop,
    isCollapsed: props.isCollapsed ?? false,
    setIsCollapsed: props.setIsCollapsed ?? noop,
    containerElement,
    pageContentElement: getHtmlElement(pageContentEl)
  });

  // use @popperjs/core to set initial position for the panel
  useLayoutEffect(() => {
    if (!panelRef.current) {
      return;
    }
    panelRef.current.focus();
    if (initialState && !initialStateAppliedOnce.current) {
      initialStateAppliedOnce.current = true;
      return setPosition(initialState);
    }
    if (!anchorEl) {
      return;
    }
    const popperInstance = createPopper(getHtmlElement(anchorEl), panelRef.current, {
      placement,
      strategy: 'fixed',
      modifiers: popperModifiers,
      onFirstUpdate: () => {
        const {
          left,
          top
        } = panelRef.current.getBoundingClientRect();
        setPosition(state => ({
          ...state,
          left,
          top
        }));
        popperInstance.destroy();
      }
    });
  }, [placement]);
  return /*#__PURE__*/_jsx(FloatingPanelContext.Provider, {
    value: context,
    children: /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/_jsxs("section", {
      ref: panelRef,
      "test-id": testId,
      className: classnames('floating-panel', {
        docked: isDocked,
        collapsed: isCollapsed
      })
      /* eslint-disable-next-line react/forbid-dom-props */,
      style: style,
      "aria-modal": "true",
      role: "dialog",
      "aria-label": props.ariaLabel || t('Floating panel'),
      "aria-describedby": "floating-panel-content",
      tabIndex: -1,
      children: [/*#__PURE__*/_jsx(FloatingPanelHeader, {
        ref: headerRef,
        onClose: onClose,
        getPosition: getPosition,
        isDocked: isDocked,
        setIsDocked: setIsDocked,
        actions: actions,
        dragIcon: dragIcon
      }), /*#__PURE__*/_jsx("div", {
        id: "floating-panel-content",
        className: "floating-panel-content",
        children: children
      }), !isDocked && resizeHandles.map(handle => /*#__PURE__*/_jsx(DraggableArea, {
        areaId: handle.id,
        className: classnames('resize-handle', handle.id),
        onDrag: onResize,
        onDragStart: onMovementStart,
        onDragEnd: onResizeEnd
      }, handle.id))]
    }), containerElement)
  });
}