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

import React, { Component, cloneElement, Children } from 'react';
import { safeInvoke } from '../utils';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Measure from 'react-measure';
import { CLS_PREFIX } from '../../constants';
import Pagination from '../Pagination';
import Grid from '../Grid';
import GridCol from '../GridCol';
import Button from '../Button';
import Spinner from '../Spinner';
import Translate from '../Translate';
import CardListToolbar from './CardListToolbar';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
export const VIEW_TILE = 'tile';
export const VIEW_RESPONSIVE = 'responsive';
export const VIEW_EXTENDED = 'extended';
export const VIEW_ROW = 'row';

/**
 * @deprecated `CardList` was used for displaying list of objects presented in various data formats
 * including images and other interface components.
 * Now it is deprecated and [List should be used](#!/List) instead.
 * @since 0.0.54
 */
class CardList extends Component {
  constructor() {
    super(...arguments);
    _defineProperty(this, "state", {
      page: this.props.defaultPage,
      totalItems: this.props.totalItems || this.props.items.length,
      pageSize: 10,
      items: this.props.items,
      view: this.props.view
    });
    _defineProperty(this, "selectAll", () => {
      const {
        items
      } = this.state;
      this.select(items.map(this.getItemKey));
    });
    _defineProperty(this, "selectNone", () => {
      this.select([]);
    });
    _defineProperty(this, "getItemKey", item => {
      const {
        itemKey
      } = this.props;
      return item[itemKey];
    });
    _defineProperty(this, "renderItem", item => {
      const {
        baseClassName,
        itemRender,
        onSelectionChange
      } = this.props;
      const {
        view
      } = this.state;
      return /*#__PURE__*/cloneElement(itemRender(item), {
        key: this.getItemKey(item),
        view: this.isTile() ? VIEW_TILE : view,
        className: classNames(`${baseClassName}__list-item`),
        selection: onSelectionChange ? this.itemSelection(item) : null
      });
    });
    _defineProperty(this, "previousView", null);
    _defineProperty(this, "handleResize", _ref => {
      let {
        bounds: {
          width
        }
      } = _ref;
      const view = width > 584 ? this.previousView : VIEW_RESPONSIVE;
      if (view === VIEW_RESPONSIVE && !this.previousView) {
        this.previousView = this.state.view;
      } else if (view !== VIEW_RESPONSIVE) {
        this.previousView = null;
      }
      if (view && view !== this.state.view) {
        this.changeView(view);
      }
    });
  }
  static getDerivedStateFromProps(props, state) {
    const {
      items,
      totalItems
    } = props;
    const {
      prevItems,
      prevTotalItems
    } = state;
    const nextState = {};
    if (items !== prevItems) {
      nextState.items = items;
    }
    if (totalItems !== prevTotalItems) {
      nextState.totalItems = totalItems || items.length;
    }
    nextState.prevItems = items;
    nextState.prevTotalItems = totalItems || items.length;
    return nextState;
  }
  componentDidMount() {
    this.fetchItems();
  }
  componentDidUpdate(prevProps) {
    const {
      view
    } = this.props;
    if (view !== prevProps.view && this.state.view !== VIEW_RESPONSIVE) {
      this.fetchItems({
        page: 1,
        view
      });
    }
  }
  totalPages() {
    const {
      totalItems,
      pageSize
    } = this.state;
    return Math.ceil(totalItems / pageSize);
  }
  fetchItems() {
    let {
      page = this.state.page,
      view = this.state.view
    } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    const {
      onItemsFetch
    } = this.props;
    const pageSize = view === VIEW_ROW ? 40 : 10;
    this.setState({
      view,
      page,
      pageSize
    });
    safeInvoke(onItemsFetch, {
      page,
      pageSize
    });
  }
  loadMore() {
    const {
      onItemsFetch
    } = this.props;
    const {
      page
    } = this.state;
    const nextPage = page + 1;
    this.setState({
      page: nextPage,
      pageSize: 10
    });
    safeInvoke(onItemsFetch, {
      page: nextPage,
      pageSize: 10
    });
  }
  isTile() {
    const {
      view
    } = this.state;
    return view === VIEW_TILE || view === VIEW_RESPONSIVE;
  }
  renderPagination() {
    const {
      baseClassName
    } = this.props;
    const {
      page,
      view
    } = this.state;
    const totalPages = this.totalPages();
    if (totalPages < 2) {
      return null;
    }
    if (view === VIEW_RESPONSIVE && page < totalPages) {
      return /*#__PURE__*/_jsx("div", {
        className: `${baseClassName}__pagination`,
        children: /*#__PURE__*/_jsx(Button, {
          onClick: () => this.loadMore(),
          children: /*#__PURE__*/_jsx(Translate, {
            content: 'CardList.loadMore',
            fallback: 'Load more'
          })
        })
      });
    }
    return /*#__PURE__*/_jsx(Pagination, {
      className: `${baseClassName}__pagination`,
      total: totalPages,
      current: page,
      onSelect: page => this.fetchItems({
        page
      })
    });
  }
  changeView(view) {
    const {
      onViewChange
    } = this.props;
    this.fetchItems({
      page: 1,
      view
    });
    safeInvoke(onViewChange, view);
  }
  select(keys) {
    const {
      onSelectionChange
    } = this.props;
    onSelectionChange(keys);
  }
  itemSelection(item) {
    const key = this.getItemKey(item);
    const {
      selection
    } = this.props;
    return {
      isSelected: selection.indexOf(key) > -1,
      onSelectionChange: _ref2 => {
        let {
          isSelected
        } = _ref2;
        const keys = isSelected ? [...selection, key] : selection.filter(k => k !== key);
        this.select(keys);
      }
    };
  }
  renderLoader() {
    const {
      baseClassName,
      loading
    } = this.props;
    if (!loading) {
      return null;
    }
    return /*#__PURE__*/_jsx("div", {
      className: `${baseClassName}__content-blocker`,
      children: /*#__PURE__*/_jsx("div", {
        className: `${baseClassName}__loader`,
        children: /*#__PURE__*/_jsx(Spinner, {
          className: `${baseClassName}__loader-spinner`
        })
      })
    });
  }
  render() {
    const {
      baseClassName,
      className,
      items,
      onItemsFetch,
      view,
      itemKey,
      itemRender,
      onViewChange,
      selection,
      onSelectionChange,
      selectionButton,
      viewSwitcher,
      toolbarGroups,
      totalItems,
      defaultPage,
      loading,
      ...props
    } = this.props;
    let content = this.state.items.map(this.renderItem);
    if (this.isTile()) {
      content = /*#__PURE__*/_jsx(Grid, {
        minColumnWidth: 400,
        gap: "md",
        children: Children.map(content, child => /*#__PURE__*/_jsx(GridCol, {
          children: child
        }, child.props.key))
      });
    }
    return /*#__PURE__*/_jsx(Measure, {
      bounds: true,
      onResize: this.handleResize,
      children: _ref3 => {
        let {
          measureRef
        } = _ref3;
        return /*#__PURE__*/_jsxs("div", {
          ref: measureRef,
          className: classNames(baseClassName, className),
          ...props,
          children: [/*#__PURE__*/_jsx(CardListToolbar, {
            selection: onSelectionChange && this.state.totalItems > 1 ? {
              ...selectionButton,
              total: this.state.totalItems,
              onSelectAll: this.selectAll,
              onSelectNone: this.selectNone,
              checked: this.state.items.length === selection.length
            } : null,
            onViewChange: viewSwitcher ? view => this.changeView(view) : null,
            currentView: this.state.view,
            groups: toolbarGroups
          }), this.state.items.length > 0 && /*#__PURE__*/_jsx("div", {
            className: `${baseClassName}__list ${baseClassName}__list--${this.state.view}`,
            children: content
          }), this.state.items.length === 0 && !loading && /*#__PURE__*/_jsx(Translate, {
            content: "CardList.notFound",
            fallback: "No items found."
          }), this.renderPagination(), this.renderLoader()]
        });
      }
    });
  }
}
CardList.propTypes = {
  /**
   * Array of data items for rendering.
   * @since 0.0.68
   */
  items: PropTypes.array.isRequired,
  /**
   * Callback for fetching items.
   * @since 0.0.68
   */
  onItemsFetch: PropTypes.func,
  /**
   * Total items. Equal items.length by default.
   * @since 0.0.68
   */
  totalItems: PropTypes.number,
  /**
   * Default page number.
   * @since 1.0.1
   */
  defaultPage: PropTypes.number,
  /**
   * View mode.
   * @since 0.0.54
   */
  view: PropTypes.oneOf([VIEW_EXTENDED, VIEW_TILE, VIEW_ROW, VIEW_RESPONSIVE]),
  /**
   * View change callback.
   * @since 0.0.54
   */
  onViewChange: PropTypes.func,
  /**
   * View switcher config.
   * @since 0.0.59
   */
  viewSwitcher: PropTypes.bool,
  /**
   * Array of keys of selected cards.
   * @since 0.0.59
   */
  selection: PropTypes.array,
  /**
   * Selection change handler for list. Checkboxes will only be rendered if this prop is defined.
   * @since 0.0.59
   */
  onSelectionChange: PropTypes.func,
  /**
   * Config for selection button in the toolbar.
   * @since 0.0.59
   */
  selectionButton: PropTypes.shape({
    /**
     * See [Badge](#!/Badge) for all props.
     */
    badge: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    /**
     * Array of additional [MenuItems](#!/MenuItem).
     */
    menuItems: PropTypes.arrayOf(PropTypes.element)
  }),
  /**
   * Toolbar groups for the toolbar.
   * @since 0.0.59
   */
  toolbarGroups: PropTypes.arrayOf(PropTypes.element),
  /**
   * Unique key.
   * @since 0.0.59
   */
  itemKey: PropTypes.string.isRequired,
  /**
   * Render function for item.
   * @since 0.0.59
   */
  itemRender: PropTypes.func.isRequired,
  /**
   * Indicate the loading state of the list.
   * @since 0.0.68
   */
  loading: PropTypes.bool,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * @ignore
   */
  baseClassName: PropTypes.string
};
CardList.defaultProps = {
  onItemsFetch: null,
  totalItems: null,
  defaultPage: 1,
  view: VIEW_EXTENDED,
  onViewChange: null,
  viewSwitcher: false,
  selection: [],
  onSelectionChange: null,
  selectionButton: {
    badge: null,
    menuItems: []
  },
  toolbarGroups: [],
  loading: false,
  className: null,
  baseClassName: `${CLS_PREFIX}card-list`
};
export default CardList;