type Props = {
  totalPages: number;
  currentPage: number;
  onChange: (page: number) => void;
  visiblePages?: number;
};

const Pagination = ({
  totalPages,
  currentPage,
  onChange,
  visiblePages = 5,
}: Props) => {
  const DOTS = '...';

  const getPaginationRange = (
    totalPages: number,
    currentPage: number,
    visiblePages: number = 5,
  ): (number | string)[] => {
    const totalPageNumbers = visiblePages + 4;

    if (totalPages <= totalPageNumbers) {
      return Array.from({ length: totalPages }, (_, i) => i + 1);
    }

    const middlePages = Math.floor(visiblePages / 2);
    let start = Math.max(currentPage - middlePages, 2);
    let end = Math.min(currentPage + middlePages, totalPages - 1);

    if (currentPage <= middlePages + 2) {
      start = 2;
      end = visiblePages + 1;
    }

    if (currentPage >= totalPages - (middlePages + 1)) {
      start = totalPages - visiblePages;
      end = totalPages - 1;
    }

    const pages: (number | string)[] = [];

    pages.push(1);

    if (start > 2) {
      pages.push(DOTS);
    }

    for (let i = start; i <= end; i++) {
      pages.push(i);
    }

    if (end < totalPages - 1) {
      pages.push(DOTS);
    }

    pages.push(totalPages);

    return pages;
  };

  const paginationRange = getPaginationRange(
    totalPages,
    currentPage,
    visiblePages,
  );

  return (
    <div className="flex justify-center mt-6 space-x-2 flex-wrap">
      <button
        onClick={() => onChange(currentPage - 1)}
        disabled={currentPage === 1}
        className="size-[35px] border text-[20px] rounded font-medium bg-white text-muted border-muted disabled:opacity-50"
      >
        {'<'}
      </button>

      {paginationRange.map((page, idx) =>
        page === DOTS ? (
          <span key={`dots-${idx}`} className="pt-3 font-medium text-muted">
            ...
          </span>
        ) : (
          <button
            key={`page-${page}`}
            onClick={() => onChange(Number(page))}
            className={`size-[35px] border rounded font-medium cursor-pointer duration-150 ${
              page === currentPage
                ? 'bg-secondary text-white border-secondary hover:brightness-110'
                : 'bg-white text-muted border-muted hover:bg-gray-100'
            }`}
          >
            {page}
          </button>
        ),
      )}

      <button
        onClick={() => onChange(currentPage + 1)}
        disabled={currentPage === totalPages}
        className="size-[35px] text-[20px] border rounded font-medium bg-white text-muted border-muted disabled:opacity-50"
      >
        {'>'}
      </button>
    </div>
  );
};

export default Pagination;
