import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
// Copyright 1999-2021. Plesk International GmbH. All rights reserved.
import React, { Component, Children, cloneElement, isValidElement } from 'react';
import classNames from 'classnames';
import { CLS_PREFIX } from '../../constants';
import Grid from '../Grid';
import GridCol from '../GridCol';
import { safeInvoke } from '../utils';

const getNextSelectedValue = (value, prevValue, toggleable) => {
  if (Array.isArray(prevValue)) {
    if (prevValue.indexOf(value) !== -1) {
      if (toggleable) {
        return prevValue.filter(v => v !== value);
      }

      return prevValue;
    }

    return [...prevValue, value];
  }

  if (toggleable && prevValue === value) {
    return null;
  }

  return value;
};

/**
 * `ItemList` component is used for displaying list of [Items](#!/Item)
 * according to [Grid](#!/Grid) principle.
 * @since 0.0.48
 */
class ItemList extends Component {
  constructor(_props) {
    super(_props); // eslint-disable-next-line react/state-in-constructor

    _defineProperty(this, "createItemProps", item => {
      const {
        baseClassName,
        selectable,
        onSelect,
        reorderable
      } = this.props;
      const classNameList = ["".concat(baseClassName, "__item")];
      const props = {};

      if (selectable && item.props.value !== undefined) {
        const {
          value
        } = this.state;
        const itemValue = item.props.value;

        if (Array.isArray(value) && value.indexOf(itemValue) !== -1) {
          classNameList.push("".concat(baseClassName, "__item--selected"));
        } else if (value === itemValue) {
          classNameList.push("".concat(baseClassName, "__item--selected"));
        }

        props.onClick = e => {
          safeInvoke(item.props.onClick, e);
          const nextValue = getNextSelectedValue(itemValue, value, selectable === 'toggleable' || selectable === 'multiple');
          this.setState({
            value: nextValue
          });
          safeInvoke(onSelect, nextValue);
        };
      }

      if (reorderable) {
        classNameList.push("".concat(baseClassName, "__item--reorderable"));
      }

      classNameList.push(item.props.className);
      props.className = classNames(...classNameList);
      return props;
    });

    this.state = {
      ReorderableGrid: null,
      ReorderableGridCol: null,
      value: typeof _props.defaultValue === 'undefined' ? null : _props.defaultValue
    };
  }

  static getDerivedStateFromProps({
    selectable,
    value: propValue
  }, state) {
    if (selectable) {
      const multiple = selectable === 'multiple';
      const safeValue = multiple ? [] : null;
      const value = typeof propValue === 'undefined' ? state.value : propValue;

      if (multiple && !Array.isArray(value)) {
        if (value) {
          return {
            value: [value]
          };
        }

        return {
          value: safeValue
        };
      } else if (!multiple && Array.isArray(value)) {
        if (value[0]) {
          return {
            value: value[0]
          };
        }

        return {
          value: safeValue
        };
      }

      return {
        value
      };
    }

    return null;
  }

  componentDidMount() {
    const {
      reorderable
    } = this.props;

    if (reorderable) {
      // @ts-ignore
      import(
      /* webpackChunkName: "react-sortable-hoc" */
      'react-sortable-hoc').then(({
        sortableContainer,
        sortableElement
      }) => {
        this.setState({
          ReorderableGrid: sortableContainer(Grid),
          ReorderableGridCol: sortableElement(GridCol)
        });
      });
    }
  }

  renderNormal({
    baseClassName,
    children,
    ...props
  }) {
    return /*#__PURE__*/React.createElement(Grid, props, Children.map(children, child => {
      if ( /*#__PURE__*/isValidElement(child)) {
        return /*#__PURE__*/React.createElement(GridCol, {
          className: classNames("".concat(baseClassName, "__col"))
        }, /*#__PURE__*/cloneElement(child, this.createItemProps(child)));
      }

      return null;
    }));
  }

  hasViewCard() {
    const {
      children
    } = this.props;
    let result = false;
    Children.forEach(children, child => {
      if (child && child.props && child.props.view === 'card') {
        result = true;
      }
    });
    return result;
  }

  renderReorderable({
    baseClassName,
    onReorderEnd,
    children,
    ...props
  }) {
    const {
      ReorderableGrid,
      ReorderableGridCol
    } = this.state;

    if (!ReorderableGrid) {
      return null;
    }

    const helperClass = classNames({
      ["".concat(baseClassName, "__col--gap-xs")]: props.gap === 'xs',
      ["".concat(baseClassName, "__col--gap-sm")]: props.gap === 'sm',
      ["".concat(baseClassName, "__col--gap-md")]: props.gap === 'md',
      ["".concat(baseClassName, "__col--gap-lg")]: props.gap === 'lg',
      ["".concat(baseClassName, "__col--gap-xl")]: props.gap === 'xl'
    });
    return /*#__PURE__*/React.createElement(ReorderableGrid, _extends({
      axis: "xy",
      helperClass: helperClass,
      onSortEnd: onReorderEnd
    }, props), Children.map(children, (child, index) => {
      if ( /*#__PURE__*/isValidElement(child)) {
        const {
          disabled
        } = child.props;
        return /*#__PURE__*/React.createElement(ReorderableGridCol, {
          index: index,
          className: classNames("".concat(baseClassName, "__col")),
          disabled: disabled
        }, /*#__PURE__*/cloneElement(child, this.createItemProps(child)));
      }

      return null;
    }));
  }

  render() {
    const {
      className,
      reorderable,
      hoverable,
      stretchable,
      selectable,
      onSelect,
      value,
      defaultValue,
      onReorderEnd,
      ...props
    } = this.props;
    return /*#__PURE__*/React.createElement("div", {
      className: classNames(this.props.baseClassName, {
        ["".concat(this.props.baseClassName, "--hoverable")]: hoverable && !reorderable && !selectable,
        ["".concat(this.props.baseClassName, "--stretchable")]: stretchable,
        ["".concat(this.props.baseClassName, "--selectable")]: selectable,
        ["".concat(this.props.baseClassName, "--cards")]: this.hasViewCard()
      }, className)
    }, reorderable ? this.renderReorderable({
      onReorderEnd,
      ...props
    }) : this.renderNormal(props));
  }

}

_defineProperty(ItemList, "defaultProps", {
  hoverable: true,
  stretchable: false,
  reorderable: false,
  selectable: false,
  baseClassName: "".concat(CLS_PREFIX, "item-list")
});

export default ItemList;