import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _excluded = ["captureClick", "closeOnTab", "handleBackspaceDeleteKeydown", "handleClickOutside", "handleEnterKeydown", "handleEscapeKeydown", "handleKeyDown"];
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
import React, { PureComponent, useCallback, useEffect, useRef, useState } from 'react';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
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 var OutsideClickTargetRefContext = /*#__PURE__*/React.createContext(function () {
  return Object;
});

// This needs exporting to be used alongside `withReactEditorViewOuterListeners`
// Ignored via go/ees005
// eslint-disable-next-line @repo/internal/react/no-class-components
var WithOutsideClick = /*#__PURE__*/function (_PureComponent) {
  function WithOutsideClick() {
    var _this;
    _classCallCheck(this, WithOutsideClick);
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _callSuper(this, WithOutsideClick, [].concat(args));
    _defineProperty(_this, "handleClick", function (evt) {
      var _this$props$outsideCl;
      if (!_this.props.isActiveComponent || !_this.props.handleClickOutside) {
        return;
      }
      var 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 || _this$props$editorVie2.focus();
        }
      }
    });
    _defineProperty(_this, "handleKeyDown", function (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 (expValEquals('platform_editor_block_menu', 'isEnabled', true)) {
        var _this$props$handleKey, _this$props;
        (_this$props$handleKey = (_this$props = _this.props).handleKeyDown) === null || _this$props$handleKey === void 0 || _this$props$handleKey.call(_this$props, evt);
      }
    });
    return _this;
  }
  _inherits(WithOutsideClick, _PureComponent);
  return _createClass(WithOutsideClick, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      if (this.props.handleClickOutside) {
        var 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 && expValEquals('platform_editor_block_menu', 'isEnabled', 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);
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      if (this.props.handleClickOutside) {
        var 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 && expValEquals('platform_editor_block_menu', 'isEnabled', 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);
      }
    }
  }, {
    key: "render",
    value: function render() {
      return this.props.children;
    }
  }]);
}(PureComponent);
// 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 function (_ref) {
    var captureClick = _ref.captureClick,
      closeOnTab = _ref.closeOnTab,
      handleBackspaceDeleteKeydown = _ref.handleBackspaceDeleteKeydown,
      handleClickOutside = _ref.handleClickOutside,
      handleEnterKeydown = _ref.handleEnterKeydown,
      handleEscapeKeydown = _ref.handleEscapeKeydown,
      handleKeyDown = _ref.handleKeyDown,
      props = _objectWithoutProperties(_ref, _excluded);
    var isActiveProp = hasIsOpen(props) ? props.isOpen : true;
    var _useState = useState(false),
      _useState2 = _slicedToArray(_useState, 2),
      isActiveComponent = _useState2[0],
      setActiveComponent = _useState2[1];
    var outsideClickTargetRef = useRef(null);
    var setOutsideClickTargetRef = useCallback(function (el) {
      outsideClickTargetRef.current = el && new WeakRef(el);
    }, [outsideClickTargetRef]);
    useEffect(function () {
      requestAnimationFrame(function () {
        setActiveComponent(isActiveProp);
      });
    }, [isActiveProp]);
    return /*#__PURE__*/React.createElement(ReactEditorViewContext.Consumer, null, function (_ref2) {
      var editorView = _ref2.editorView,
        popupsMountPoint = _ref2.popupsMountPoint,
        editorRef = _ref2.editorRef;
      return /*#__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)));
    });
  };
}