import _defineProperty from "@babel/runtime/helpers/defineProperty";
// Copyright 1999-2023. Plesk International GmbH. All rights reserved.

import classNames from 'classnames';
import { Component, createRef } from 'react';
import { CLS_PREFIX } from '../../constants';
import Button from '../Button';
import ButtonGroup from '../ButtonGroup';
import Dropdown from '../Dropdown';
import Menu, { MenuItem } from '../Menu';
import ResponsiveContext from '../ResponsiveContext';
import Squeezer from '../Squeezer';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const alphaSort = (a, b) => a > b ? 1 : -1;
export const SEGMENTED_CONTROL_BASE_CLASS_NAME = `${CLS_PREFIX}segmented-control`;

/**
 *  `Segmented Control` is a group of several [Buttons](#!/Button)
 * each of which functions as a mutually exclusive option.
 * @since 0.0.68
 */
class SegmentedControl extends Component {
  constructor() {
    super(...arguments);
    _defineProperty(this, "state", {
      selected: this.props.selected,
      monoWidth: 0
    });
    _defineProperty(this, "context", void 0);
    _defineProperty(this, "isCompact", false);
    _defineProperty(this, "rootRef", /*#__PURE__*/createRef());
    _defineProperty(this, "adjustMonospaced", () => {
      const {
        baseClassName,
        monospaced
      } = this.props;
      if (monospaced) {
        let monoWidth = 0;
        this.rootRef.current?.querySelectorAll(`.${baseClassName}__button`).forEach(el => {
          monoWidth = Math.max(monoWidth, el.getBoundingClientRect().width);
        });
        if (monoWidth !== this.state.monoWidth) {
          this.setState({
            monoWidth
          });
        }
      }
    });
    _defineProperty(this, "handleChange", value => () => {
      const {
        multiple,
        onChange
      } = this.props;
      const {
        selected
      } = this.state;
      let newSelected;
      if (multiple) {
        newSelected = selected && Array.isArray(selected) ? selected.slice() : [];
        if (!selected || !(selected instanceof Array) || selected.indexOf(value) === -1) {
          newSelected.push(value);
        } else {
          newSelected.splice(selected.indexOf(value), 1);
        }
        newSelected.sort(alphaSort);
        this.setState({
          selected: newSelected
        });
        if (JSON.stringify(newSelected) !== JSON.stringify(selected)) {
          onChange?.(newSelected);
        }
      } else {
        newSelected = value;
        if (JSON.stringify(newSelected) !== JSON.stringify(selected)) {
          onChange?.(newSelected);
        }
      }
    });
    _defineProperty(this, "compact", () => {
      if (this.isCompact) {
        return false;
      }
      this.isCompact = true;
      this.forceUpdate();
      return true;
    });
    _defineProperty(this, "uncompact", () => {
      if (!this.isCompact) {
        return false;
      }
      this.isCompact = false;
      this.forceUpdate();
      return true;
    });
  }
  static getDerivedStateFromProps(props, state) {
    const {
      selected,
      multiple
    } = props;
    const {
      prevSelected
    } = state;
    const nextState = {
      selected: state.selected
    };
    if (selected !== prevSelected) {
      nextState.selected = selected;
    }
    if (multiple && nextState.selected && !(nextState.selected instanceof Array)) {
      nextState.selected = [nextState.selected];
    }
    nextState.prevSelected = selected;
    return nextState;
  }
  componentDidMount() {
    this.adjustMonospaced();
  }
  componentDidUpdate() {
    this.adjustMonospaced();
  }
  isResponsive() {
    return this.context === undefined ? this.isCompact : this.context;
  }
  renderControl() {
    const {
      buttons,
      multiple
    } = this.props;
    const hasIcons = buttons.some(_ref => {
      let {
        icon
      } = _ref;
      return !!icon;
    });
    if (!hasIcons && !multiple && this.isResponsive()) {
      return this.renderDropdown();
    }
    return this.renderButtonGroup();
  }
  renderDropdown() {
    const {
      buttons,
      onChange
    } = this.props;
    const {
      selected
    } = this.state;
    const {
      title = ''
    } = buttons.find(button => button.value === selected) || {};
    const menu = /*#__PURE__*/_jsx(Menu, {
      children: buttons.map(_ref2 => {
        let {
          title,
          value,
          ...buttonProps
        } = _ref2;
        const menuItemProps = {};
        if (onChange !== null) {
          menuItemProps.onClick = this.handleChange(value);
        }
        return /*#__PURE__*/_jsx(MenuItem, {
          ...buttonProps,
          ...menuItemProps,
          children: title
        }, `${value}`);
      })
    });
    return /*#__PURE__*/_jsx(Dropdown, {
      menu: menu,
      children: title
    });
  }
  renderButtonGroup() {
    const {
      buttons,
      monospaced,
      multiple,
      onChange,
      ghost,
      baseClassName
    } = this.props;
    const {
      selected,
      monoWidth
    } = this.state;
    const isCollapsed = this.state.compact;
    return /*#__PURE__*/_jsx(ButtonGroup, {
      className: `${baseClassName}__button-group`,
      children: buttons.map(_ref3 => {
        let {
          value,
          title,
          ...buttonProps
        } = _ref3;
        // uncontrolled
        const handler = {};
        if (onChange !== null) {
          handler.onClick = this.handleChange(value);
        }
        let buttonSelected = false;
        if (multiple && selected && selected instanceof Array && selected.indexOf(value) !== -1) {
          buttonSelected = true;
        } else if (!multiple && selected === value) {
          buttonSelected = true;
        }
        buttonProps.className = classNames(buttonProps.className, `${baseClassName}__button`);
        if (!isCollapsed && monospaced && monoWidth) {
          buttonProps.style = {
            width: monoWidth,
            ...buttonProps.style
          };
        }
        return /*#__PURE__*/_jsx(Button, {
          selected: buttonSelected,
          ghost: ghost,
          ...handler,
          ...buttonProps,
          children: title
        }, `${value}`);
      })
    });
  }
  render() {
    const {
      label,
      labelPlacement,
      buttons,
      monospaced,
      multiple,
      selected: selectedProp,
      onChange,
      inline,
      ghost,
      className,
      baseClassName,
      ...props
    } = this.props;
    const isCollapsed = this.isResponsive();
    return /*#__PURE__*/_jsx(ResponsiveContext.Provider, {
      value: isCollapsed,
      children: /*#__PURE__*/_jsx(Squeezer, {
        compact: this.compact,
        uncompact: this.uncompact,
        innerRef: el => {
          // @ts-ignore
          this.rootRef.current = el;
        },
        children: _ref4 => {
          let {
            ref
          } = _ref4;
          return /*#__PURE__*/_jsxs("div", {
            ref: ref,
            className: classNames(baseClassName, {
              [`${baseClassName}--inline`]: inline,
              [`${baseClassName}--collapsed`]: isCollapsed,
              [`${baseClassName}--vertical`]: label && labelPlacement === 'top'
            }, className),
            ...props,
            children: [label && /*#__PURE__*/_jsx("div", {
              className: `${baseClassName}__label`,
              children: label
            }), this.renderControl()]
          });
        }
      })
    });
  }
}
_defineProperty(SegmentedControl, "defaultProps", {
  label: null,
  labelPlacement: 'top',
  monospaced: false,
  multiple: false,
  onChange: null,
  inline: false,
  ghost: false,
  className: null,
  baseClassName: SEGMENTED_CONTROL_BASE_CLASS_NAME
});
_defineProperty(SegmentedControl, "contextType", ResponsiveContext);
export default SegmentedControl;