<script lang="ts">
  import { cn } from '$lib/utils'
  import { buttonVariants } from '$lib/button-variants'

  interface Props {
    currentPage: number
    totalPages: number
    baseUrl: string
  }

  let { currentPage, totalPages, baseUrl }: Props = $props()

  function getPageUrl(page: number): string {
    if (page === 1) return baseUrl
    return `${baseUrl}${page}`
  }

  function getVisiblePages(): number[] {
    const maxVisiblePages = 6
    const pages: number[] = []

    if (totalPages <= maxVisiblePages) {
      for (let i = 1; i <= totalPages; i++) {
        pages.push(i)
      }
    } else {
      const startPage = Math.max(1, currentPage - 2)
      const endPage = Math.min(totalPages, currentPage + 2)

      if (startPage > 1) pages.push(1)
      if (startPage > 2) pages.push(-1) // ellipsis marker

      for (let i = startPage; i <= endPage; i++) {
        pages.push(i)
      }

      if (endPage < totalPages - 1) pages.push(-1) // ellipsis marker
      if (endPage < totalPages) pages.push(totalPages)
    }

    return pages
  }

  let visiblePages = $derived(getVisiblePages())
</script>

<nav
  role="navigation"
  aria-label="pagination"
  data-slot="pagination"
  class="mx-auto flex w-full justify-center"
>
  <ul
    data-slot="pagination-content"
    class="flex flex-row flex-wrap items-center gap-1"
  >
    <!-- Previous Button -->
    <li data-slot="pagination-item">
      <a
        href={currentPage > 1 ? getPageUrl(currentPage - 1) : undefined}
        aria-label="Go to previous page"
        data-slot="pagination-link"
        data-disabled={currentPage === 1 ? true : undefined}
        class={cn(
          buttonVariants({ variant: 'ghost', size: 'default' }),
          'gap-1 px-2.5 sm:pl-2.5',
          currentPage === 1 && 'pointer-events-none opacity-50'
        )}
      >
        <!-- ChevronLeft icon -->
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4">
          <path d="m15 18-6-6 6-6"/>
        </svg>
        <span class="hidden sm:block">Previous</span>
      </a>
    </li>

    <!-- Page Numbers -->
    {#each visiblePages as page, index}
      {#if page === -1}
        <!-- Ellipsis -->
        <li data-slot="pagination-item">
          <span
            aria-hidden="true"
            data-slot="pagination-ellipsis"
            class="flex size-9 items-center justify-center"
          >
            <!-- MoreHorizontal icon -->
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4">
              <circle cx="12" cy="12" r="1"/>
              <circle cx="19" cy="12" r="1"/>
              <circle cx="5" cy="12" r="1"/>
            </svg>
            <span class="sr-only">More pages</span>
          </span>
        </li>
      {:else}
        <!-- Page Number -->
        <li data-slot="pagination-item">
          <a
            href={getPageUrl(page)}
            aria-current={page === currentPage ? 'page' : undefined}
            data-slot="pagination-link"
            data-active={page === currentPage ? true : undefined}
            class={cn(
              buttonVariants({
                variant: page === currentPage ? 'outline' : 'ghost',
                size: 'icon',
              })
            )}
          >
            {page}
          </a>
        </li>
      {/if}
    {/each}

    <!-- Next Button -->
    <li data-slot="pagination-item">
      <a
        href={currentPage < totalPages ? getPageUrl(currentPage + 1) : undefined}
        aria-label="Go to next page"
        data-slot="pagination-link"
        data-disabled={currentPage === totalPages ? true : undefined}
        class={cn(
          buttonVariants({ variant: 'ghost', size: 'default' }),
          'gap-1 px-2.5 sm:pr-2.5',
          currentPage === totalPages && 'pointer-events-none opacity-50'
        )}
      >
        <span class="hidden sm:block">Next</span>
        <!-- ChevronRight icon -->
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4">
          <path d="m9 18 6-6-6-6"/>
        </svg>
      </a>
    </li>
  </ul>
</nav>
