import React from 'react';
import { faChevronLeft } from '@fortawesome/free-solid-svg-icons/faChevronLeft';
import { faChevronRight } from '@fortawesome/free-solid-svg-icons/faChevronRight';
import { FontAwesomeIcon } from '../font-awesome-icon';
import { BUTTON_TYPES } from '../button';
import { useTranslation } from '../hooks/use-translation';
import { DropdownMenu, DROPDOWN_MENU_PLACEMENT_TYPES } from '../dropdown-menu';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/* USAGE EXAMPLE
  <PaginationControls
    total={this.state.total}
    count={this.state.count}
    currentPage={this.state.currentPage}
    pageSize={this.state.pageSize}
    availableSizes={this.state.paginationOptions}
    onPageChange={this.handlePageChange}
    onPageSizeChange={this.handlePageSizeChange}
  />
*/

const STEP = 1;
const START_PAGE = 0;
/** Pagination allows navigate through pages and change page size. */
export default function PaginationControls(props) {
  const {
    t
  } = useTranslation();
  const buildTriggerLabel = data => {
    const {
      isDisabled,
      isExceededTotalLimit,
      startOfPage,
      endOfPage,
      total,
      totalLimit
    } = data;
    let triggerContent;
    if (isDisabled) {
      triggerContent = t('0-0 of 0');
    } else if (endOfPage === null) {
      triggerContent = isExceededTotalLimit ? t('{{startOfPage}} of {{totalLimit}}', {
        startOfPage,
        totalLimit
      }) : t('{{startOfPage}} of {{total}}', {
        startOfPage,
        total
      });
    } else {
      triggerContent = isExceededTotalLimit ? t('{{startOfPage}}-{{endOfPage}} of {{totalLimit}}+', {
        startOfPage,
        endOfPage,
        totalLimit
      }) : t('{{startOfPage}}-{{endOfPage}} of {{total}}', {
        startOfPage,
        endOfPage,
        total
      });
    }
    return /*#__PURE__*/_jsx("span", {
      children: triggerContent
    });
  };
  return /*#__PURE__*/_jsx(PaginationControlsBase, {
    prevPageAriaLabel: t('Previous page'),
    nextPageAriaLabel: t('Next page'),
    noPageSizesText: t('No available page sizes'),
    buildTriggerLabel: buildTriggerLabel,
    ...props
  });
}
class PaginationControlsBase extends React.Component {
  constructor(props) {
    super(props);
    this.getLabel = this.getLabel.bind(this);
    this.next = this.next.bind(this);
    this.prev = this.prev.bind(this);
    this.shouldShowPaginationDropdown = this.shouldShowPaginationDropdown.bind(this);
    if (props.totalLimit && props.nextPage === undefined) {
      throw new Error('PaginationControls must be used with defined nextPage if totalLimit is used');
    }
  }
  next() {
    const {
      onPageChange,
      currentPage,
      pageSize
    } = this.props;
    if (this.isOnLastPage()) {
      return;
    }
    onPageChange(currentPage + STEP, pageSize);
  }
  prev() {
    const {
      onPageChange,
      currentPage,
      pageSize
    } = this.props;
    if (this.isOnFirstPage()) {
      return;
    }
    onPageChange(currentPage - STEP, pageSize);
  }
  changeSize(size) {
    const {
      onPageChange,
      onPageSizeChange,
      pageSize,
      currentPage
    } = this.props;
    if (pageSize === size) {
      return;
    }
    onPageSizeChange?.(size);
    if (currentPage !== START_PAGE) {
      onPageChange(START_PAGE, size);
    }
  }
  isOnFirstPage() {
    return this.props.currentPage === START_PAGE;
  }
  isOnLastPage() {
    if (this.isExceededTotalLimit()) {
      return !this.props.nextPage;
    }
    const numPages = Math.ceil(this.props.total / (this.props.pageSize ?? 1)); // if pageSize is not defined - assume it's 1
    return this.props.currentPage >= numPages - STEP;
  }
  isExceededTotalLimit() {
    const {
      total,
      totalLimit
    } = this.props;
    return !!totalLimit && total >= totalLimit;
  }
  getPageStart() {
    const {
      currentPage,
      pageSize,
      total
    } = this.props;
    if (total !== 0 && pageSize && pageSize >= total) {
      return 1;
    }
    return total === 0 ? START_PAGE : currentPage * (pageSize ?? 1) + STEP;
  }
  getPageEnd() {
    const {
      currentPage,
      pageSize,
      count,
      total
    } = this.props;
    const currentCount = (currentPage + STEP) * (pageSize ?? 1);
    if (this.isExceededTotalLimit() && total < currentCount && count) {
      return Math.min(currentCount, (pageSize ?? 1) * currentPage + count);
    }
    return Math.min(currentCount, total);
  }
  getLabel() {
    const {
      total,
      isDisabled,
      buildTriggerLabel,
      totalLimit,
      pageSize,
      onPageSizeChange
    } = this.props;
    const isEndOfPageAvailable = !!pageSize && !!onPageSizeChange;
    const startOfPage = this.getPageStart();
    const endOfPage = isEndOfPageAvailable ? this.getPageEnd() : null;
    return typeof buildTriggerLabel === 'function' ? buildTriggerLabel({
      isDisabled,
      startOfPage,
      endOfPage,
      total,
      totalLimit,
      isExceededTotalLimit: this.isExceededTotalLimit()
    }) : null;
  }
  getPageSizeOptions() {
    return this.generateSizeOptions();
  }
  generateSizeOptions() {
    const {
      total,
      availableSizes
    } = this.props;
    const sizeOptions = availableSizes?.length ? availableSizes : [20, 50, 100];
    if (total === 0 || total <= sizeOptions[0]) {
      return [];
    }
    const filteredSizes = sizeOptions.filter(option => option <= total);
    if (filteredSizes.length < sizeOptions.length) {
      return [...filteredSizes, total];
    }
    return sizeOptions;
  }
  generateDropdownPaginationOptions() {
    return this.getPageSizeOptions().map(option => ({
      id: String(option),
      key: option,
      title: option,
      activeItemId: String(option),
      testId: 'pagination-menu-item'
    }));
  }
  shouldShowPaginationDropdown() {
    return this.props.pageSize && this.props.onPageSizeChange;
  }
  render() {
    const {
      isDisabled,
      pageSize,
      testId,
      isLoading,
      prevPageAriaLabel,
      nextPageAriaLabel,
      noPageSizesText
    } = this.props;
    return /*#__PURE__*/_jsxs("menu", {
      className: "control-pagination",
      "test-id": testId,
      children: [/*#__PURE__*/_jsx("button", {
        "aria-label": prevPageAriaLabel,
        className: "button command page-number-button",
        "test-id": "pagination-control-prev-page",
        onClick: this.prev,
        disabled: this.isOnFirstPage() || isDisabled || isLoading,
        type: BUTTON_TYPES.BUTTON,
        children: /*#__PURE__*/_jsx(FontAwesomeIcon, {
          icon: faChevronLeft
        })
      }), this.shouldShowPaginationDropdown() ? /*#__PURE__*/_jsx(DropdownMenu, {
        triggerDynamicContent: this.getLabel,
        triggerTestId: "pagination-control-label",
        triggerClassName: "page-size-button",
        wrapperContentTestId: "page-size-dropdown-content",
        options: this.generateDropdownPaginationOptions(),
        noResultsText: noPageSizesText,
        selectedKey: pageSize,
        isDisabled: isDisabled,
        onSelect: option => {
          this.changeSize(option?.key);
        },
        contentTestId: "pagination-control-menu",
        placement: DROPDOWN_MENU_PLACEMENT_TYPES.BOTTOM
      }) : /*#__PURE__*/_jsx("span", {
        className: "pagination-simple-label",
        "test-id": "pagination-simple-label",
        children: this.getLabel()
      }), /*#__PURE__*/_jsx("button", {
        "aria-label": nextPageAriaLabel,
        className: "button command page-number-button",
        "test-id": "pagination-control-next-page",
        onClick: this.next,
        disabled: this.isOnLastPage() || isDisabled || isLoading,
        type: BUTTON_TYPES.BUTTON,
        children: /*#__PURE__*/_jsx(FontAwesomeIcon, {
          icon: faChevronRight
        })
      })]
    });
  }
}