import { Link, useLocation } from 'react-router-dom'

import type { FC } from 'react'

type Props = { page:          number
	       totalPages:    number
	       siblingCount?: number }


const range = (start: number, end: number): number[] =>
    [...Array (end - start + 1).keys ()].map (i => start + i)


const getPages = (
    page:         number,
    total:        number,
    siblingCount: number,
): (number | '…')[] => {
  if (total <= 1)
    return [1]

  const first = 1
  const last = total

  const left = Math.max (page - siblingCount, first)
  const right = Math.min (page + siblingCount, last)

  const pages: (number | '…')[] = []

  pages.push (first)

  if (left > first + 1)
    pages.push ('…')

  const midStart = Math.max (left, first + 1)
  const midEnd = Math.min (right, last - 1)
  pages.push (...range (midStart, midEnd))

  if (right < last - 1)
    pages.push ('…')

  if (last !== first)
    pages.push (last)

  return pages.filter ((v, i, arr) => i === 0 || v !== arr[i - 1])
}


export default (({ page, totalPages, siblingCount = 4 }) => {
  const location = useLocation ()

  const buildTo = (p: number) => {
    const qs = new URLSearchParams (location.search)
    qs.set ('page', String (p))
    return `${ location.pathname }?${ qs.toString () }`
  }

  const pages = getPages (page, totalPages, siblingCount)

  return (
      <nav className="mt-4 flex justify-center" aria-label="Pagination">
	<div className="flex items-center gap-2">
	  {(page > 1)
	   ? <Link to={buildTo (page - 1)} aria-label="前のページ">&lt;</Link>
	   : <span aria-hidden>&lt;</span>}

	  {pages.map ((p, idx) => (
	      (p === '…')
	      ? <span key={`dots-${ idx }`}>…</span>
	      : ((p === page)
		 ? <span key={p} className="font-bold" aria-current="page">{p}</span>
		 : <Link key={p} to={buildTo (p)}>{p}</Link>)))}

	  {(page < totalPages)
	   ? <Link to={buildTo (page + 1)} aria-label="次のページ">&gt;</Link>
	   : <span aria-hidden>&gt;</span>}
	</div>
      </nav>)
}) satisfies FC<Props>
