import { ChevronLeftIcon, ChevronRightIcon } from '@trail-ui/icons';
import { useMemo } from 'react';
import { CustomSelect } from '../select';
import { Positions } from '../overlay';
import { IconButton } from '../button';

export interface PaginationProps {
  totalCount: number;
  size: number;
  currentPage: number;
  selectedCount: number;
  onPageChange: (nextPageNumber: number) => void;
  onPageSizeChange?: (size: number) => void;
  readsResults?: boolean;
  sizeOptions?: number[];
}
export default function Pagination({ readsResults = true, ...props }: PaginationProps) {
  const totalPages = useMemo(() => {
    return Math.ceil(props.totalCount / props.size);
  }, [props.totalCount, props.size]);

  const pageNumberArray: (number | '...')[] = useMemo(() => {
    const maxButtonsToShow = 5;
    const pageNumbers: (number | '...')[] = [];
    if (totalPages <= maxButtonsToShow) {
      for (let i = 1; i <= totalPages; i++) {
        pageNumbers.push(i);
      }
      return pageNumbers;
    }

    // biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>
    // biome-ignore lint/style/useSingleVarDeclarator: <explanation>
    let startPage, endPage;
    const middleButtonsToShow = maxButtonsToShow - 2;
    const halfMiddleButtonsToShow = Math.floor(middleButtonsToShow / 2);

    if (props.currentPage <= halfMiddleButtonsToShow + 1) {
      startPage = 2;
      endPage = middleButtonsToShow + 1;
    } else if (props.currentPage + halfMiddleButtonsToShow >= totalPages) {
      startPage = totalPages - middleButtonsToShow;
      endPage = totalPages - 1;
    } else {
      startPage = props.currentPage - halfMiddleButtonsToShow;
      endPage = props.currentPage + halfMiddleButtonsToShow;
    }

    pageNumbers.push(1);
    if (startPage > 2) {
      pageNumbers.push('...');
    }

    for (let i = startPage; i <= endPage; i++) {
      pageNumbers.push(i);
    }

    if (endPage < totalPages - 1) {
      pageNumbers.push('...');
    }
    pageNumbers.push(totalPages);

    return pageNumbers;
  }, [props.totalCount, props.size, props.currentPage]);

  return (
    <div className="flex flex-wrap items-center justify-between gap-4 space-x-2">
      <div className="flex flex-wrap items-center gap-4">
        {props.onPageSizeChange && (
          <div className="flex items-center gap-2">
            <span className="min-w-[fit-content] text-sm font-normal text-neutral-600">
              Items per page
            </span>
            <CustomSelect
              label="Items per page"
              classNames={{
                label: 'hidden',
              }}
              value={props.size}
              isRequired={false}
              options={
                props.sizeOptions?.map((size) => ({
                  label: size.toString(),
                  value: size,
                })) || [
                  { label: '100', value: 100 },
                  { label: '250', value: 250 },
                  { label: '500', value: 500 },
                ]
              }
              errorMessage={''}
              errorId={''}
              onChange={(e) => {
                props.onPageSizeChange?.(Number(e));
                props.onPageChange(1);
              }}
              position={Positions.topLeft}
              popover={{ width: 100 }}
              allowDeselection={false}
            />
          </div>
        )}

        {readsResults ? (
          // biome-ignore lint/a11y/useSemanticElements: <explanation>
          <p
            role="status"
            aria-live="polite"
            aria-atomic="true"
            className="text-sm text-neutral-600"
          >
            Showing {(props.currentPage - 1) * props.size + 1}-
            {Math.min(props.currentPage * props.size, props.totalCount)} of {props.totalCount}{' '}
            {props.totalCount === 1 ? 'result' : 'results'}
          </p>
        ) : (
          <p className="text-sm text-neutral-600">
            Showing {(props.currentPage - 1) * props.size + 1}-
            {Math.min(props.currentPage * props.size, props.totalCount)} of {props.totalCount}{' '}
            {props.totalCount === 1 ? 'result' : 'results'}
          </p>
        )}
      </div>

      {props.selectedCount > 0 && (
        <p
          role={props.selectedCount < 1 ? 'none' : 'alert'}
          aria-live={props.selectedCount < 1 ? 'off' : 'polite'}
          className={`${props.selectedCount < 1 ? 'sr-only' : ''} text-sm font-medium text-purple-600`}
        >
          {props.selectedCount} selected
        </p>
      )}

      <nav aria-label="Pagination" className="flex justify-end">
        <ul className="flex items-center justify-end gap-2">
          <li className="flex h-8 w-8 items-center justify-center">
            <IconButton
              aria-label="Previous Page"
              appearance="transparent"
              isDisabled={props.currentPage === 1}
              onPress={() => {
                props.onPageChange?.(props.currentPage - 1);
              }}
            >
              <ChevronLeftIcon
                color={`${props.currentPage === 1 ? '#B0ACBB' : '#302E38'}`}
                width={24}
                height={24}
              />
            </IconButton>
          </li>

          {pageNumberArray.map((pageNumber: any, index) => (
            <li
              className="flex h-8 w-8 items-center justify-center"
              key={`${pageNumber}-${
                // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
                index
              }`}
            >
              {pageNumber === '...' ? (
                <span>...</span>
              ) : (
                <button
                  data-id={pageNumber}
                  {...(pageNumber === props.currentPage ? { 'aria-current': 'page' } : {})}
                  aria-current={pageNumber === props.currentPage ? 'page' : undefined}
                  aria-label={`Page ${pageNumber}`}
                  onClick={() => {
                    if (pageNumber !== '...' && props.onPageChange) {
                      props.onPageChange(pageNumber);
                    }
                  }}
                  className={`h-full w-full text-sm font-normal text-neutral-800 focus:outline-purple-600 ${
                    pageNumber === props.currentPage
                      ? 'rounded border border-purple-600 bg-purple-100'
                      : 'bg-white'
                  } `}
                >
                  {pageNumber}
                </button>
              )}
            </li>
          ))}
          <li className="flex h-8 w-8 items-center justify-center">
            <IconButton
              aria-label="Next Page"
              appearance="transparent"
              isDisabled={props.currentPage >= totalPages}
              onPress={() => {
                props.onPageChange?.(props.currentPage + 1);
              }}
            >
              <ChevronRightIcon
                color={props.currentPage === totalPages ? '#B0ACBB' : '#302E38'}
                width={24}
                height={24}
              />
            </IconButton>
          </li>
        </ul>
      </nav>
    </div>
  );
}
