import React, { useCallback } from "react";
import PropTypes from "prop-types";
import cn from "classnames";
import PageItem from "./pagination-item";
import IPaginationProps from "./pagination.d";

const Pagination = (props: IPaginationProps) => {
  const {
    className,
    currentPageIndex,
    itemCount,
    adjacentShowCount = 2,
    disabled = false,
    onPageChange = () => {},
    pageSize = 20,
    backButtonProps = { ariaLabel: "Previous", children: "«" },
    forwardButtonProps = { ariaLabel: "Forward", children: "»" }
  } = props;

  const totalPages = Math.floor((itemCount + pageSize - 1) / pageSize);
  const currentIndex = Math.max(0, Math.min(currentPageIndex, totalPages - 1));
  const pageIndexes = [currentIndex];

  while (pageIndexes.length < Math.min(totalPages, adjacentShowCount * 2 + 1)) {
    const left = pageIndexes[0] - 1;
    if (left >= 0) {
      pageIndexes.unshift(left);
    }

    const right = pageIndexes[pageIndexes.length - 1] + 1;
    if (right < totalPages) {
      pageIndexes.push(right);
    }
  }

  const updatePage = useCallback(
    (newPage: number) => {
      const nextPage = Math.max(0, Math.min(totalPages - 1, newPage));
      if (nextPage != currentIndex) {
        onPageChange(nextPage);
      }
    },
    [totalPages, currentIndex]
  );

  const testId = props["data-testid"] || "honeyui-pagination";

  return (
    <nav data-testid={testId}>
      <ul className={cn("pagination", className)} data-testid={`${testId}-list`}>
        <PageItem
          disabled={disabled || currentIndex - 1 < 0}
          onClick={() => updatePage(currentIndex - 1)}
          data-testid={`${testId}-item-back`}
          aria-label={backButtonProps.ariaLabel}
        >
          {backButtonProps.children}
        </PageItem>
        {pageIndexes.map(idx => {
          return (
            <PageItem
              key={idx}
              active={idx === currentIndex}
              disabled={disabled}
              onClick={() => updatePage(idx)}
              aria-label={`Page ${idx}`}
              data-testid={`${testId}-item-${idx}`}
            >
              {idx + 1}
            </PageItem>
          );
        })}
        <PageItem
          disabled={disabled || currentIndex + 1 > totalPages - 1}
          onClick={() => updatePage(currentIndex + 1)}
          data-testid={`${testId}-item-forward`}
          aria-label={forwardButtonProps.ariaLabel}
        >
          {forwardButtonProps.children}
        </PageItem>
      </ul>
    </nav>
  );
};

Pagination.displayName = "Pagination";

Pagination.defaultProps = {
  adjacentShowCount: 2,
  className: "",
  disabled: false,
  onPageChange: () => {},
  pageSize: 20,
  backButtonProps: { ariaLabel: "Previous", children: "«" },
  forwardButtonProps: { ariaLabel: "Forward", children: "»" }
};

Pagination.propTypes = {
  adjacentShowCount: PropTypes.number,
  backButtonProps: PropTypes.any,
  className: PropTypes.string,
  currentPageIndex: PropTypes.number.isRequired,
  forwardButtonProps: PropTypes.any,
  itemCount: PropTypes.number.isRequired,
  onPageChange: PropTypes.func,
  pageSize: PropTypes.number
};

export default Pagination;
