import _defineProperty from "@babel/runtime/helpers/defineProperty";
import React, { PureComponent, useCallback, useEffect, useRef, useState } from 'react';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import ReactEditorViewContext from './ReactEditorViewContext';
// Use this context to pass in the reference of the element that should be considered as the outside click target
// The outside click target is the element that should be clicked outside of to trigger the `handleClickOutside` event
export const OutsideClickTargetRefContext = /*#__PURE__*/React.createContext(() => Object);

// This needs exporting to be used alongside `withReactEditorViewOuterListeners`

// Ignored via go/ees005
// eslint-disable-next-line @repo/internal/react/no-class-components
class WithOutsideClick extends PureComponent {
  constructor(...args) {
    super(...args);
    _defineProperty(this, "handleClick", evt => {
      var _this$props$outsideCl;
      if (!this.props.isActiveComponent || !this.props.handleClickOutside) {
        return;
      }
      const domNode = (_this$props$outsideCl = this.props.outsideClickTargetRef.current) === null || _this$props$outsideCl === void 0 ? void 0 : _this$props$outsideCl.deref();
      if (!domNode || evt.target instanceof Node && !domNode.contains(evt.target)) {
        var _this$props$editorVie;
        this.props.handleClickOutside(evt);
        // When the menus are closed by clicking outside the focus is set on editor.
        if (!((_this$props$editorVie = this.props.editorView) !== null && _this$props$editorVie !== void 0 && _this$props$editorVie.hasFocus())) {
          var _this$props$editorVie2;
          (_this$props$editorVie2 = this.props.editorView) === null || _this$props$editorVie2 === void 0 ? void 0 : _this$props$editorVie2.focus();
        }
      }
    });
    _defineProperty(this, "handleKeyDown", evt => {
      if (!this.props.isActiveComponent) {
        return;
      }
      if (evt.code === 'Escape' && this.props.handleEscapeKeydown) {
        evt.preventDefault();
        evt.stopPropagation();
        this.props.handleEscapeKeydown(evt);
        // on 'Esc', Focus is handled in 'handleEscapeKeydown'.
        return false;
      } else if (evt.code === 'Enter' && this.props.handleEnterKeydown) {
        this.props.handleEnterKeydown(evt);
      } else if (evt.code === 'Tab' && this.props.handleEscapeKeydown && this.props.closeOnTab) {
        // The menus should be closed when the tab is pressed as it takes the focus out of the menu
        this.props.handleEscapeKeydown(evt);
      } else if ((evt.code === 'Delete' || evt.code === 'Backspace') && this.props.handleBackspaceDeleteKeydown) {
        this.props.handleBackspaceDeleteKeydown(evt);
      }
      if (editorExperiment('platform_editor_block_menu', true, {
        exposure: true
      })) {
        var _this$props$handleKey, _this$props;
        (_this$props$handleKey = (_this$props = this.props).handleKeyDown) === null || _this$props$handleKey === void 0 ? void 0 : _this$props$handleKey.call(_this$props, evt);
      }
    });
  }
  componentDidMount() {
    if (this.props.handleClickOutside) {
      const options = this.props.captureClick && editorExperiment('platform_editor_controls', 'variant1') ? {
        capture: true
      } : false;
      // Ignored via go/ees005
      // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
      document.addEventListener('click', this.handleClick, options);
    }
    if (this.props.handleEscapeKeydown || this.props.handleBackspaceDeleteKeydown || this.props.handleKeyDown && editorExperiment('platform_editor_block_menu', true, {
      exposure: true
    })) {
      var _this$props$editorRef;
      // Attached event to the menu so that 'ESC' events from the opened menu also will be handled.
      // Ignored via go/ees005
      // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
      (this.props.popupsMountPoint ? this.props.popupsMountPoint :
      // @ts-ignore - TS2873 TypeScript 5.9.2 upgrade
      undefined || ((_this$props$editorRef = this.props.editorRef) === null || _this$props$editorRef === void 0 ? void 0 : _this$props$editorRef.current) || this.props.targetRef || document

      // Ignored via go/ees005
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      ).addEventListener('keydown', this.handleKeyDown, false);
    }
  }
  componentWillUnmount() {
    if (this.props.handleClickOutside) {
      const options = this.props.captureClick && editorExperiment('platform_editor_controls', 'variant1') ? {
        capture: true
      } : false;
      // Ignored via go/ees005
      // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
      document.removeEventListener('click', this.handleClick, options);
    }
    if (this.props.handleEscapeKeydown || this.props.handleBackspaceDeleteKeydown || this.props.handleKeyDown && editorExperiment('platform_editor_block_menu', true, {
      exposure: true
    })) {
      var _this$props$editorRef2;
      // Ignored via go/ees005
      // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
      (this.props.popupsMountPoint ? this.props.popupsMountPoint :
      // @ts-ignore - TS2873 TypeScript 5.9.2 upgrade
      undefined || ((_this$props$editorRef2 = this.props.editorRef) === null || _this$props$editorRef2 === void 0 ? void 0 : _this$props$editorRef2.current) || this.props.targetRef || document

      // Ignored via go/ees005
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      ).removeEventListener('keydown', this.handleKeyDown, false);
    }
  }
  render() {
    return this.props.children;
  }
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function hasIsOpen(props) {
  return 'isOpen' in props;
}
export default function withReactEditorViewOuterListeners(Component) {
  return ({
    captureClick,
    closeOnTab,
    handleBackspaceDeleteKeydown,
    handleClickOutside,
    handleEnterKeydown,
    handleEscapeKeydown,
    handleKeyDown,
    ...props
  }) => {
    const isActiveProp = hasIsOpen(props) ? props.isOpen : true;
    const [isActiveComponent, setActiveComponent] = useState(false);
    const outsideClickTargetRef = useRef(null);
    const setOutsideClickTargetRef = useCallback(el => {
      outsideClickTargetRef.current = el && new WeakRef(el);
    }, [outsideClickTargetRef]);
    useEffect(() => {
      requestAnimationFrame(() => {
        setActiveComponent(isActiveProp);
      });
    }, [isActiveProp]);
    return /*#__PURE__*/React.createElement(ReactEditorViewContext.Consumer, null, ({
      editorView,
      popupsMountPoint,
      editorRef
    }) => /*#__PURE__*/React.createElement(OutsideClickTargetRefContext.Provider, {
      value: setOutsideClickTargetRef
    }, /*#__PURE__*/React.createElement(WithOutsideClick, {
      editorView: editorView,
      editorRef: editorRef,
      targetRef: props.targetRef,
      outsideClickTargetRef: outsideClickTargetRef,
      popupsMountPoint: popupsMountPoint,
      isActiveComponent: isActiveComponent,
      handleClickOutside: handleClickOutside,
      handleEnterKeydown: handleEnterKeydown,
      handleEscapeKeydown: handleEscapeKeydown,
      handleBackspaceDeleteKeydown: handleBackspaceDeleteKeydown,
      handleKeyDown: handleKeyDown,
      closeOnTab: closeOnTab,
      captureClick: captureClick
    }, /*#__PURE__*/React.createElement(Component
    // Ignored via go/ees005
    // eslint-disable-next-line react/jsx-props-no-spreading
    , props))));
  };
}