import { useCallback } from "preact/compat";
import Button from "../Button/Button";
import Ellipses from "./Ellipses";
import Page from "./Page";
import classNames from 'classnames';
import { ArrowIcon } from "../Icons";
import { t } from "../i18n";
import { jsx as _jsx } from "preact/compat/jsx-runtime";
import { jsxs as _jsxs } from "preact/compat/jsx-runtime";
// Determines number of pages visible to either side of active page.
const overflow = 1;

// Determines total number of visible pages without Ellipses.
const maxVisiblePages = 7;
function paginationBuilder(page, pages) {
  const paginationRange = [];
  let start = page - overflow;
  let end = page + overflow;
  const availableSlots = maxVisiblePages - 2;

  /**
   * If the current page is < `maxVisiblePages`,
   * add 1 - 5 pages.
   */
  if (page < availableSlots) {
    start = 1;
    end = availableSlots;
  }

  /**
   * If the current page equals `pages` - 1,
   * make sure `start` begins one page earlier.
   */
  if (page === pages - 2) {
    start -= 1;
    end += 1;
  }

  /**
   * If `end` page is two from the end,
   * make sure the last page shows instead of ellipsis.
   */
  if (end === pages - 2) {
    end += 1;
  }

  /**
   * If `end` > `pages`,
   * add last pages to `paginationRange[]`.
   */
  if (end >= pages) {
    start = pages - (availableSlots - 1);
    end = pages;
  }

  /**
   * If `pages` is 5 or fewer,
   * all pages added to `paginationRange[]`
   */
  if (pages <= maxVisiblePages) {
    start = 1;
    end = pages;
  }
  for (let i = start; i <= end; i++) {
    paginationRange.push(i);
  }
  return paginationRange;
}

/**
 * For information about how and when to use this component,
 * [refer to its full documentation page](https://design.cms.gov/components/pagination/).
 */
function Pagination(_ref) {
  let {
    ariaLabel,
    className,
    compact,
    currentPage,
    renderHref,
    onPageChange,
    headingLevel,
    isNavigationHidden,
    startLabelText,
    startAriaLabel,
    endLabelText,
    endAriaLabel,
    totalPages,
    ...rest
  } = _ref;
  const classes = classNames('ds-c-pagination', {
    'ds-c-pagination--compact': compact
  }, className);

  /**
   * `useState` and `useEffect` determine if
   * mobile layout of component is rendered.
   */

  const pageChange = useCallback(page => evt => onPageChange(evt, page), [onPageChange]);
  const pages = [];

  /**
   * If `compact` is true, don't run code to populate `pages[]`.
   */
  if (!compact) {
    const pageRange = paginationBuilder(currentPage, totalPages);
    if (pageRange[0] >= 2) {
      /**
       * If `pageRange` begins with a page of 2 or greater,
       * begin Pagination with Page 1
       */
      pages.push( /*#__PURE__*/_jsx(Page, {
        href: renderHref(1),
        index: 1,
        isActive: currentPage === 1,
        onPageChange: pageChange(1)
      }, "page-1"));

      /**
       * If `pageRange` doesn't equal 2, second Pagination element is Ellipses,
       * otherwise page count continues.
       */
      if (pageRange[0] !== 2) {
        pages.push( /*#__PURE__*/_jsx(Ellipses, {}, "ellipses-1"));
      }
    }

    /**
     * Renders all Page components in range (3 pages) to Pagination component.
     */

    pageRange.forEach(page => {
      pages.push( /*#__PURE__*/_jsx(Page, {
        href: renderHref(page),
        index: page,
        isActive: currentPage === page,
        onPageChange: pageChange(page)
      }, `page-${page}`));
    });

    /**
     * Defines if/when the Ellipses component appears
     * at the end of the Pagination component -
     * as long as there are fewer than 7 pages.
     */
    if (currentPage <= totalPages - 3 && totalPages > maxVisiblePages) {
      if (currentPage < totalPages - 3) {
        pages.push( /*#__PURE__*/_jsx(Ellipses, {}, "ellipses-2"));
      }
      pages.push( /*#__PURE__*/_jsx(Page, {
        href: renderHref(totalPages),
        index: totalPages,
        isActive: currentPage === totalPages,
        onPageChange: pageChange(totalPages)
      }, `page-${totalPages}`));
    }
  }
  const startIcon = /*#__PURE__*/_jsx(ArrowIcon, {
    direction: "left",
    className: "ds-c-pagination__nav--image"
  });
  const endIcon = /*#__PURE__*/_jsx(ArrowIcon, {
    direction: "right",
    className: "ds-c-pagination__nav--image"
  });
  const Heading = `h${headingLevel}`;
  const headingElement = /*#__PURE__*/_jsxs(Heading, {
    id: "pagination-heading",
    children: [ariaLabel ?? t('pagination.ariaLabel'), " -", ' ', t('pagination.pageXOfY', {
      number: `${currentPage}`,
      total: `${totalPages}`
    })]
  });
  return /*#__PURE__*/_jsxs("nav", {
    className: classes,
    "aria-labelledby": "pagination-heading",
    ...rest,
    children: [/*#__PURE__*/_jsx("span", {
      className: "ds-u-visibility--screen-reader",
      children: headingElement
    }), /*#__PURE__*/_jsxs(Button, {
      variation: "ghost",
      href: renderHref(currentPage - 1),
      onClick: pageChange(currentPage - 1),
      "aria-label": startAriaLabel ?? t('pagination.startAriaLabel'),
      className: "ds-c-pagination__nav",
      disabled: currentPage === 1,
      style: {
        visibility: currentPage === 1 && isNavigationHidden ? 'hidden' : 'visible'
      },
      "aria-hidden": currentPage === 1 ? isNavigationHidden : false,
      children: [/*#__PURE__*/_jsx("span", {
        className: "ds-c-pagination__nav--img-container ds-c-pagination__nav--img-container-previous",
        children: startIcon
      }), startLabelText ?? t('pagination.startLabelText')]
    }), /*#__PURE__*/_jsx("span", {
      className: "ds-c-pagination__page-count",
      dangerouslySetInnerHTML: {
        __html: t('pagination.pageXOfY', {
          number: `<strong>${currentPage}</strong>`,
          total: `<strong>${totalPages}</strong>`
        })
      }
    }), /*#__PURE__*/_jsx("div", {
      className: "ds-c-pagination__pages",
      children: pages
    }), /*#__PURE__*/_jsxs(Button, {
      variation: "ghost",
      href: renderHref(currentPage + 1),
      onClick: pageChange(currentPage + 1),
      "aria-label": endAriaLabel ?? t('pagination.endAriaLabel'),
      className: "ds-c-pagination__nav",
      disabled: currentPage === totalPages,
      style: {
        visibility: currentPage === totalPages && isNavigationHidden ? 'hidden' : 'visible'
      },
      "aria-hidden": currentPage === totalPages ? isNavigationHidden : false,
      children: [endLabelText ?? t('pagination.endLabelText'), /*#__PURE__*/_jsx("span", {
        className: "ds-c-pagination__nav--img-container ds-c-pagination__nav--img-container-next",
        children: endIcon
      })]
    })]
  });
}
Pagination.defaultProps = {
  compact: false,
  headingLevel: '2',
  isNavigationHidden: false
};
export default Pagination;