import styles from './Pagination.module.css'
import type { HTMLAttributes } from 'react'

interface PaginationProps extends HTMLAttributes<HTMLElement> {
  page: number
  totalPages: number
  onPageChange: (page: number) => void
  siblingCount?: number
  className?: string
}

export function getPageRange(
  page: number,
  totalPages: number,
  siblingCount: number
): (number | 'ellipsis')[] {
  if (totalPages <= 1) return [1]

  // If total pages fit in a compact window, just return all pages with no ellipsis
  const totalPageNumbers = siblingCount * 2 + 5 // 1(first) + 1(last) + 1(current) + 2*siblings + 2(ellipsis slots)
  if (totalPages <= totalPageNumbers) {
    return Array.from({ length: totalPages }, (_, i) => i + 1)
  }

  const range: (number | 'ellipsis')[] = []

  const left = Math.max(2, page - siblingCount)
  const right = Math.min(totalPages - 1, page + siblingCount)

  // First page always shown
  range.push(1)

  // Left ellipsis: gap between 1 and left boundary hides at least 1 page
  if (left > 2) {
    range.push('ellipsis')
  }

  // Middle pages
  for (let i = left; i <= right; i++) {
    range.push(i)
  }

  // Right ellipsis: gap between right boundary and last page hides at least 1 page
  if (right < totalPages - 1) {
    range.push('ellipsis')
  }

  // Last page always shown
  range.push(totalPages)

  return range
}

export function Pagination({
  page,
  totalPages,
  onPageChange,
  siblingCount = 1,
  className,
  ...rest
}: PaginationProps) {
  const pageRange = getPageRange(page, totalPages, siblingCount)

  return (
    <nav
      aria-label="Pagination"
      className={`${styles.pagination} ${className ?? ''}`}
      {...rest}
    >
      <button
        className={styles.navBtn}
        onClick={() => onPageChange(page - 1)}
        disabled={page <= 1}
        aria-label="Previous page"
      >
        &lt;
      </button>

      {pageRange.map((item, idx) => {
        if (item === 'ellipsis') {
          return (
            <span key={`ellipsis-${idx}`} className={styles.ellipsis} aria-hidden="true">
              &hellip;
            </span>
          )
        }

        const isActive = item === page
        return (
          <button
            key={item}
            className={`${styles.pageBtn} ${isActive ? styles.active : ''}`}
            onClick={() => onPageChange(item)}
            aria-current={isActive ? 'page' : undefined}
            aria-label={`Page ${item}`}
            disabled={isActive}
          >
            {item}
          </button>
        )
      })}

      <button
        className={styles.navBtn}
        onClick={() => onPageChange(page + 1)}
        disabled={page >= totalPages}
        aria-label="Next page"
      >
        &gt;
      </button>
    </nav>
  )
}
