<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { pagination } from 'alga-js/array'

const props = defineProps<{
  modelValue: number,
  pages: number,
  items?: string[],
  ellipsis?: number,
  type?: string
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: number): void,
  (e: 'handler', value: number): void
}>()

const currentPage = ref<number>(props?.modelValue || 1)
const goToPageInput = ref<string>('')

watch(() => props.modelValue, () => {
  currentPage.value = props.modelValue
})

const getPagination = computed<any[]>(() => {
  let newPagination = []
  if(props?.items) {
    newPagination = props?.items || []
  } else {
    const totalPages = props.pages
    const positionOfEllipsis = props?.ellipsis || 2
    newPagination = pagination(totalPages, currentPage.value, positionOfEllipsis)
  }
  return newPagination
})

const emitCurrentPage = (page: number) => {
  currentPage.value = page
  emit('update:modelValue', currentPage.value)
  emit('handler', currentPage.value)
}

const goToPage = () => {
  const page = Number(goToPageInput.value)
  if(page >= 1 && page <= props.pages) {
    emitCurrentPage(page)
    goToPageInput.value = ''
  }
}
</script>

<template>
  <div class="pagination-wrapper">
    <ul class="pagination" :class="['dense', 'sparse'].includes(type) ? type : ''">
      <li class="item">
        <span class="link" @click="emitCurrentPage(1)">
          &laquo;
        </span>
      </li>
      <li class="item">
        <span class="link" @click="emitCurrentPage((Number(currentPage) > 1) ? Number(currentPage) - 1 : 1)">
          &lsaquo;
        </span>
      </li>
      <li v-for="(item, index) in getPagination" :key="'item-'+index" class="item" :class="Number(item) === Number(currentPage) ? 'active' : ''">
        <span v-if="Number(item) === Number(currentPage)" class="link">{{ item }}</span>
        <span v-else-if="item === '...'" class="link">{{ item }}</span>
        <span v-else @click="emitCurrentPage(Number(item))" class="link">{{ item }}</span>
      </li>
      <li class="item">
        <span class="link" @click="emitCurrentPage((Number(currentPage) < Number(pages)) ? Number(currentPage) + 1 : Number(pages))">
          &rsaquo;
        </span>
      </li>
      <li class="item">
        <span class="link" @click="emitCurrentPage(Number(pages))">
          &raquo;
        </span>
      </li>
    </ul>
    <div v-if="pages > 1" class="go-to-page">
      <input
        v-model="goToPageInput"
        type="number"
        :min="1"
        :max="pages"
        :placeholder="`/ ${pages}`"
        class="go-to-page-input"
        @keyup.enter="goToPage"
      />
      <button class="go-to-page-btn" @click="goToPage">Go</button>
    </div>
  </div>
</template>

<style scoped>
@use pagination;

.pagination-wrapper {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.go-to-page {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.go-to-page-input {
  width: 60px;
  padding: 0.35rem 0.5rem;
  border: 1px solid #cbcbcb;
  border-radius: 5px;
  font-size: 0.85rem;
  text-align: center;
  outline: none;
}

.go-to-page-input:focus {
  border-color: #07f;
}

.go-to-page-input::-webkit-inner-spin-button,
.go-to-page-input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.go-to-page-input[type=number] {
  -moz-appearance: textfield;
}

.go-to-page-btn {
  padding: 0.35rem 0.65rem;
  border: 1px solid #cbcbcb;
  border-radius: 5px;
  background: transparent;
  cursor: pointer;
  font-size: 0.85rem;
}

.go-to-page-btn:hover {
  background-color: #eeeeee;
}

@media (prefers-color-scheme: dark) {
  .go-to-page-input {
    border-color: rgba(255,255,255,0.25);
    background-color: transparent;
    color: inherit;
  }
  .go-to-page-input:focus {
    border-color: #07f;
  }
  .go-to-page-btn {
    border-color: rgba(255,255,255,0.25);
    color: inherit;
  }
  .go-to-page-btn:hover {
    background-color: rgba(255,255,255,0.25);
  }
}
</style>