import { h, Fragment, type FunctionComponent } from 'preact'
import type { ForwardedRef } from 'preact/compat'
import cn from 'classnames'

import s from './pagination.module.scss'

function getPages({
  pathname,
  search,
  totalCount,
  limit,
  offset,
}: {
  pathname: string
  search: string
  totalCount: number
  limit: number
  offset: number
}) {
  const pages = []
  const searchParams = new URLSearchParams(search)
  const last = Math.floor(totalCount / limit)
  const current = offset / limit

  for (let i = 0; i <= last; i++) {
    if (i === 0) searchParams.delete('offset')
    else searchParams.set('offset', (limit * i) as unknown as string)

    const query = searchParams.toString()

    // TODO should all pages have a rel attribute?
    pages.push({
      path: pathname + (query ? '?' + query : ''),
      index: i,
      current: i === current,
    })
  }

  return {
    current,
    firstItemCount: totalCount ? offset + 1 : 0,
    last,
    lastItemCount: Math.min(offset + limit, totalCount),
    next: pages[current + 1],
    pages,
    prev: pages[current - 1],
    totalCount,
  }
}

type PaginationProps = {
  className?: string
  forwardRef: ForwardedRef<HTMLDivElement>
  pathname: string
  search: string
  totalCount: number
  limit: number
  offset: number
}

const Pagination: FunctionComponent<PaginationProps> = (props) => {
  const { current, last, firstItemCount, lastItemCount, totalCount, pages, prev, next } = getPages(props)

  const start = current + 3 > last ? Math.max(last - 6, 0) : Math.max(current - 3, 0)
  const end = start + 7

  return (
    <div className={cn(s.pagination, props.className)} ref={props.forwardRef}>
      <div className={s.results}>
        Showing <span className={cn(s.first, s.number)}>{firstItemCount}</span> to{' '}
        <span className={cn(s.last, s.number)}>{lastItemCount || 0}</span> of{' '}
        <span className={cn(s.total, s.number)}>{totalCount || 0}</span> entries
      </div>
      <ul className={s.pages}>
        {totalCount > 0 && (
          <Fragment>
            <li className={s.prev}>
              <a href={prev?.path || 'javascript:;'} rel={prev && 'prev'} className={s.nav} title='Previous Page'>
                Previous
              </a>
            </li>

            {pages.slice(start, end).map((page) => (
              <li key={page.index} className={cn(s.page, page.current && s.currentPage)}>
                <a href={page.path} className={s.nav} title={`Sida ${page.index + 1}`}>
                  {page.index + 1}
                </a>
              </li>
            ))}

            <li className={s.next}>
              <a href={next?.path || 'javascript:;'} rel={next && 'next'} className={s.nav} title='Next Page'>
                Next
              </a>
            </li>
          </Fragment>
        )}
      </ul>
    </div>
  )
}

export default Pagination
