import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import _ from 'lodash';
import classnames from 'classnames';
import EventBus from '../../../utils/EventBus';
import { LocalStorage } from '../../../data/LocalStorage';
import { GridSorter } from './GridSorter';
var RESIZE_OVERLAY_ID = 'GridHeaderCellResizeOverlay';
var COLUMNS_KEY = 'columns';
var RESIZE_EVENT = 'GridHeaderCellResize';
export var GridHeaderCell =
/*#__PURE__*/
function (_React$Component) {
  _inheritsLoose(GridHeaderCell, _React$Component);

  function GridHeaderCell() {
    var _this;

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;

    _defineProperty(_assertThisInitialized(_this), "state", {
      minWidth: null,
      resizing: null
    });

    _defineProperty(_assertThisInitialized(_this), "handleSiblingResize", function (localStoragePrefix) {
      var localStorage = _this.context.localStorage;
      var resizing = _this.state.resizing;

      if (resizing || !localStorage || localStoragePrefix !== localStorage.prefix) {
        return;
      }

      var cell = _this.cellRef || ReactDOM.findDOMNode(_this.gridSorterRef);

      if (!cell) {
        return;
      }

      var minWidth = _this.props.minWidth;

      if (!minWidth) {
        return;
      }

      var width = cell.clientWidth;

      if (width <= minWidth) {
        if (minWidth !== _this.state.minWidth) {
          _this.setState({
            minWidth: minWidth
          });
        } else {
          // Reset minWidth -> Render -> Re-calculate minWidth
          _this.setState({
            minWidth: null
          }, function () {
            return _this.handleSiblingResize(localStoragePrefix);
          });
        }
      } else if (_this.state.minWidth) {
        _this.setState({
          minWidth: null
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "startResizing", function (event) {
      event.stopPropagation();

      var cell = _this.getParentCell(event.target);

      if (!cell) {
        return;
      }

      var overlay = _this.createResizeOverlay();

      document.body.appendChild(overlay);
      document.addEventListener('mousemove', _this.resize);
      document.addEventListener('mouseup', _this.stopResizing);

      _this.setState({
        minWidth: null,
        resizing: {
          x: event.pageX,
          width: cell.clientWidth,
          startWidth: cell.clientWidth
        }
      });
    });

    _defineProperty(_assertThisInitialized(_this), "resize", function (event) {
      event.stopPropagation();
      var _this$props = _this.props,
          minWidth = _this$props.minWidth,
          maxWidth = _this$props.maxWidth;
      var resizing = _this.state.resizing;

      if (resizing) {
        var width = resizing.startWidth - resizing.x + event.pageX;

        if (width < minWidth) {
          width = minWidth;
        } else if (width > maxWidth) {
          width = maxWidth;
        }

        if (width !== resizing.width) {
          _this.setState({
            minWidth: null,
            resizing: Object.assign({}, resizing, {
              width: width
            })
          }, _this.notifySiblings);
        }
      }
    });

    _defineProperty(_assertThisInitialized(_this), "stopResizing", function (event) {
      event.stopPropagation();
      var localStorage = _this.context.localStorage;
      var property = _this.props.property;
      var resizing = _this.state.resizing;

      if (resizing && localStorage && property) {
        var columns = localStorage.getItem(COLUMNS_KEY) || {};
        columns[property] = Object.assign({}, columns[property], {
          width: resizing.width
        });
        localStorage.setItem(COLUMNS_KEY, columns);
      }

      _this.cancelResizing();

      _this.setState({
        resizing: null
      });
    });

    _defineProperty(_assertThisInitialized(_this), "notifySiblings", function () {
      var localStorage = _this.context.localStorage;

      if (localStorage && localStorage.prefix) {
        EventBus.emit(RESIZE_EVENT, localStorage.prefix);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "renderChildren", function (ariaDescription, skipContentForSR, ariaDescriptionId, children) {
      return React.createElement("span", null, children && React.createElement("span", {
        "aria-hidden": skipContentForSR
      }, children), ariaDescription && React.createElement("span", {
        className: "sr-only",
        id: ariaDescriptionId
      }, ariaDescription));
    });

    return _this;
  }

  var _proto = GridHeaderCell.prototype;

  _proto.componentDidMount = function componentDidMount() {
    EventBus.on(RESIZE_EVENT, this.handleSiblingResize);
  };

  _proto.componentWillUnmount = function componentWillUnmount() {
    EventBus.off(RESIZE_EVENT, this.handleSiblingResize);
    this.cancelResizing();
  };

  _proto.getResizeColumnWidth = function getResizeColumnWidth() {
    var _this$state = this.state,
        resizing = _this$state.resizing,
        minWidth = _this$state.minWidth;

    if (resizing) {
      return resizing.width;
    }

    if (minWidth) {
      return minWidth;
    }

    var localStorage = this.context.localStorage;
    var property = this.props.property;

    if (localStorage && property) {
      var columns = localStorage.getItem(COLUMNS_KEY);

      if (columns && columns[property]) {
        return columns[property].width;
      }
    }
  };

  _proto.getParentCell = function getParentCell(element) {
    var cell = element;

    while (cell && cell.tagName !== 'TH' && cell.tagName !== 'TD') {
      cell = cell.parentNode;
    }

    return cell;
  };

  _proto.createResizeOverlay = function createResizeOverlay() {
    var container = document.createElement('div');
    var overlay = document.createElement('div');
    container.id = RESIZE_OVERLAY_ID;
    container.className = 'bootstrap-rc';
    overlay.className = 'resizing-overlay resizing-overlay-ew';
    container.appendChild(overlay);
    return container;
  };

  _proto.cancelResizing = function cancelResizing() {
    var overlay = document.getElementById(RESIZE_OVERLAY_ID);

    if (overlay) {
      overlay.parentNode.removeChild(overlay);
    }

    document.removeEventListener('mousemove', this.resize);
    document.removeEventListener('mouseup', this.stopResizing);
  };

  _proto.isResizable = function isResizable() {
    var localStorage = this.context.localStorage;
    var _this$props2 = this.props,
        isResizable = _this$props2.isResizable,
        property = _this$props2.property;
    return !!(localStorage && isResizable && property);
  };

  _proto.renderResizeHandler = function renderResizeHandler() {
    if (this.props.noRightBorder) {
      return null;
    }

    var isResizable = this.isResizable();
    var className = classnames('resize-handler', {
      active: isResizable
    });
    return React.createElement("span", {
      className: className,
      onMouseDown: isResizable ? this.startResizing : null
    });
  };

  _proto.render = function render() {
    var _this2 = this;

    var _this$props3 = this.props,
        isSortable = _this$props3.isSortable,
        _isResizable = _this$props3.isResizable,
        append = _this$props3.append,
        _minWidth = _this$props3.minWidth,
        maxWidth = _this$props3.maxWidth,
        noRightBorder = _this$props3.noRightBorder,
        ariaDescription = _this$props3.ariaDescription,
        ariaDescriptionId = _this$props3.ariaDescriptionId,
        skipContentForSR = _this$props3.skipContentForSR,
        displayName = _this$props3.displayName,
        className = _this$props3.className,
        style = _this$props3.style,
        children = _this$props3.children,
        props = _objectWithoutPropertiesLoose(_this$props3, ["isSortable", "isResizable", "append", "minWidth", "maxWidth", "noRightBorder", "ariaDescription", "ariaDescriptionId", "skipContentForSR", "displayName", "className", "style", "children"]);

    var _this$state2 = this.state,
        resizing = _this$state2.resizing,
        minWidth = _this$state2.minWidth;
    var child = this.renderChildren(ariaDescription, skipContentForSR, ariaDescriptionId, children);
    var isResizable = this.isResizable();
    var resizeHandler = this.renderResizeHandler();
    var classNames = classnames(className, {
      resizable: isResizable,
      resizing: isResizable && resizing
    });
    var styles = style;

    if (isResizable) {
      var width = this.getResizeColumnWidth();

      if (width) {
        styles = Object.assign({}, styles, {
          width: width
        });
      }
    } else if (minWidth) {
      styles = Object.assign({}, styles, {
        width: minWidth
      });
    }

    if (isSortable) {
      return React.createElement(GridSorter, _extends({
        ref: function ref(th) {
          return _this2.gridSorterRef = th;
        },
        displayName: displayName || children,
        className: classNames,
        style: styles
      }, props, {
        append: append,
        prepend: resizeHandler
      }), child);
    } else {
      var testAutomationId = props.testAutomationId,
          restProps = _objectWithoutPropertiesLoose(props, ["testAutomationId"]);

      var tableHeaderProps = _.omit(restProps, Object.keys(GridHeaderCell.defaultProps));

      return React.createElement("th", _extends({
        ref: function ref(cell) {
          return _this2.cellRef = cell;
        },
        "data-test-automation-id": testAutomationId,
        className: classNames,
        style: styles
      }, tableHeaderProps), resizeHandler, append && React.createElement("span", {
        className: "column-header-append"
      }, append), React.createElement("div", {
        className: "text-overflow"
      }, child));
    }
  };

  return GridHeaderCell;
}(React.Component);

_defineProperty(GridHeaderCell, "propTypes", Object.assign({}, GridSorter.propTypes, {
  isSortable: PropTypes.bool,
  isResizable: PropTypes.bool,
  append: PropTypes.node,
  minWidth: PropTypes.number,
  maxWidth: PropTypes.number,
  ariaDescription: PropTypes.string,
  ariaDescriptionId: PropTypes.string,
  skipContentForSR: PropTypes.bool,
  noRightBorder: PropTypes.bool
}));

_defineProperty(GridHeaderCell, "defaultProps", Object.assign({}, GridSorter.defaultProps, {
  isSortable: true,
  isResizable: false,
  append: null,
  minWidth: 50,
  maxWidth: 500,
  skipContentForSR: false,
  ariaDescriptionId: null,
  noRightBorder: false
}));

_defineProperty(GridHeaderCell, "contextTypes", {
  localStorage: PropTypes.instanceOf(LocalStorage)
});