<template>
  <div v-if="pageNumbers.length > 1" class="tw-flex tw-justify-center">
    <div role="menubar" class="tw-flex">
      <button
        :class="BUTTON_CLASS"
        type="button"
        v-bind="getNavAttrs(modelValue === 1)"
        :aria-label="t('paginator.gotoFirst')"
        @click="setPage(1)"
      >
        <icon-system-uicons-push-left />
      </button>
      <button
        :class="BUTTON_CLASS"
        type="button"
        v-bind="getNavAttrs(modelValue === 1)"
        :aria-label="t('paginator.gotoPrev')"
        @click="setPage(modelValue - 1)"
      >
        <icon-system-uicons-chevron-left />
      </button>
      <template v-for="page in pageNumbers" :key="page">
        <button
          :class="[BUTTON_CLASS, { 'tw-bg-aura-primary tw-text-white': modelValue === page }]"
          type="button"
          :aria-current="modelValue === page ? 'page' : undefined"
          :aria-setsize="lastPage"
          :aria-posinset="page"
          :aria-checked="modelValue === page"
          :aria-label="t('paginator.goto', { page })"
          role="menuitemradio"
          @click="setPage(page)"
        >
          {{ page }}
        </button>
      </template>
      <button
        :class="BUTTON_CLASS"
        type="button"
        v-bind="getNavAttrs(modelValue === lastPage)"
        :aria-label="t('paginator.gotoNext')"
        @click="setPage(modelValue + 1)"
      >
        <icon-system-uicons-chevron-right />
      </button>
      <button
        :class="BUTTON_CLASS"
        type="button"
        v-bind="getNavAttrs(modelValue === lastPage)"
        :aria-label="t('paginator.gotoLast')"
        @click="setPage(lastPage)"
      >
        <icon-system-uicons-push-right />
      </button>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { useI18n } from '@/i18n'

const BUTTON_CLASS =
  'btn btn-default tw-border tw-border-solid tw-border-r-0 last:tw-border-r first:tw-rounded-l last:tw-rounded-r tw-rounded-none'

const props = defineProps<{
  modelValue: number
  itemsPerPage: number
  count: number
  maxVisiblePages?: number
}>()
const emit = defineEmits<{
  (e: 'update:modelValue', value: number): void
}>()
const { t } = useI18n()

const maxVisiblePages = computed(() => props.maxVisiblePages ?? 5)
const lastPage = computed(() => Math.max(1, Math.ceil(props.count / props.itemsPerPage)))
const pageNumbers = computed(() => {
  const result: number[] = []
  const pageOffset = Math.floor(maxVisiblePages.value / 2)
  let page = Math.max(1, props.modelValue - pageOffset)
  if (props.modelValue + pageOffset > lastPage.value)
    page = Math.max(1, page + lastPage.value - (props.modelValue + pageOffset))
  while (result.length < maxVisiblePages.value) {
    result.push(page)
    if (page === lastPage.value) break
    page++
  }
  return result
})

function getNavAttrs(isActive: boolean) {
  return isActive
    ? {
        disabled: true,
        role: 'presentation',
        'aria-hidden': true,
        'aria-disabled': true,
      }
    : { role: 'menuitem' }
}

function setPage(page: number) {
  if (page !== props.modelValue) {
    emit('update:modelValue', page)
  }
}
</script>

<script lang="ts">
export default {
  compatConfig: {
    MODE: 3,
  },
}
</script>