import type { PaginationItem } from './pagination.types'

const range = (start: number, end: number) => {
  const length = end - start + 1
  return Array.from({ length }, (_, i) => start + i)
}

/** Returns an array describing pagination items, like page buttons, prev/next arrows or ellipsis. */
export function getPaginationItems(page: number, pageCount: number) {
  const boundaryCount = 1
  const siblingCount = 1

  const startPages = range(1, Math.min(boundaryCount, pageCount))
  const endPages = range(Math.max(pageCount - boundaryCount + 1, boundaryCount + 1), pageCount)

  const siblingsStart = Math.max(
    Math.min(page - siblingCount, pageCount - boundaryCount - siblingCount * 2 - 1),
    boundaryCount + 2,
  )

  const siblingsEnd = Math.min(
    Math.max(page + siblingCount, boundaryCount + siblingCount * 2 + 2),
    endPages.length > 0 ? endPages[0] - 2 : pageCount - 1,
  )

  const items = [
    'previous',
    ...startPages,

    // Start ellipsis
    ...(siblingsStart > boundaryCount + 2
      ? ['ellipsisStart']
      : boundaryCount + 1 < pageCount - boundaryCount
        ? [boundaryCount + 1]
        : []),

    // Sibling pages
    ...range(siblingsStart, siblingsEnd),

    // End ellipsis
    ...(siblingsEnd < pageCount - boundaryCount - 1
      ? ['ellipsisEnd']
      : pageCount - boundaryCount > boundaryCount
        ? [pageCount - boundaryCount]
        : []),

    ...endPages,
    'next',
  ] as PaginationItem[]

  return items
}
