<template>
  <ul :class="nsPager.b()" @click="onPagerClick" @keyup.enter="onEnter">
    <li
      v-if="pageCount > 0"
      :class="{ [nsPager.is('active')]: currentPage === 1, disabled }"
      class="number"
      :aria-current="currentPage === 1"
      tabindex="0"
    >
      1
    </li>
    <li
      v-if="showPrevMore"
      :class="['more', 'btn-quickprev', nsIcon.b(), { disabled }]"
      @mouseenter="onMouseenter('left')"
      @mouseleave="quickPrevHover = false"
    >
      <d-arrow-left v-if="quickPrevHover" />
      <more-filled v-else />
    </li>
    <li
      v-for="pager in pagers"
      :key="pager"
      :class="{ [nsPager.is('active')]: currentPage === pager, disabled }"
      class="number"
      :aria-current="currentPage === pager"
      tabindex="0"
    >
      {{ pager }}
    </li>
    <li
      v-if="showNextMore"
      :class="['more', 'btn-quicknext', nsIcon.b(), { disabled }]"
      @mouseenter="onMouseenter('right')"
      @mouseleave="quickNextHover = false"
    >
      <d-arrow-right v-if="quickNextHover" />
      <more-filled v-else />
    </li>
    <li
      v-if="pageCount > 1"
      :class="{ [nsPager.is('active')]: currentPage === pageCount, disabled }"
      class="number"
      :aria-current="currentPage === pageCount"
      tabindex="0"
    >
      {{ pageCount }}
    </li>
  </ul>
</template>
<script lang="ts">
import { defineComponent, ref, computed, watchEffect } from 'vue'
import { MoreFilled, DArrowLeft, DArrowRight } from 'icon-ultra'
import { useNamespace } from '@element-ultra/hooks'

const paginationPagerProps = {
  currentPage: {
    type: Number,
    default: 1,
  },
  pageCount: {
    type: Number,
    required: true,
  },
  pagerCount: {
    type: Number,
    default: 7,
  },
  disabled: Boolean,
} as const

export default defineComponent({
  name: 'ElPaginationPager',

  components: {
    DArrowLeft,
    DArrowRight,
    MoreFilled,
  },
  props: paginationPagerProps,
  emits: ['change'],

  setup(props, { emit }) {
    const nsPager = useNamespace('pager')
    const nsIcon = useNamespace('icon')

    const showPrevMore = ref(false)
    const showNextMore = ref(false)
    const quickPrevHover = ref(false)
    const quickNextHover = ref(false)

    const pagers = computed(() => {
      const pagerCount = props.pagerCount
      const halfPagerCount = (pagerCount - 1) / 2
      const currentPage = Number(props.currentPage)
      const pageCount = Number(props.pageCount)

      let showPrevMore = false
      let showNextMore = false
      if (pageCount > pagerCount) {
        if (currentPage > pagerCount - halfPagerCount) {
          showPrevMore = true
        }
        if (currentPage < pageCount - halfPagerCount) {
          showNextMore = true
        }
      }
      const array: number[] = []
      if (showPrevMore && !showNextMore) {
        const startPage = pageCount - (pagerCount - 2)
        for (let i = startPage; i < pageCount; i++) {
          array.push(i)
        }
      } else if (!showPrevMore && showNextMore) {
        for (let i = 2; i < pagerCount; i++) {
          array.push(i)
        }
      } else if (showPrevMore && showNextMore) {
        const offset = Math.floor(pagerCount / 2) - 1
        for (let i = currentPage - offset; i <= currentPage + offset; i++) {
          array.push(i)
        }
      } else {
        for (let i = 2; i < pageCount; i++) {
          array.push(i)
        }
      }

      return array
    })

    watchEffect(() => {
      const halfPagerCount = (props.pagerCount - 1) / 2

      showPrevMore.value = false
      showNextMore.value = false

      if (props.pageCount > props.pagerCount) {
        if (props.currentPage > props.pagerCount - halfPagerCount) {
          showPrevMore.value = true
        }
        if (props.currentPage < props.pageCount - halfPagerCount) {
          showNextMore.value = true
        }
      }
    })

    function onMouseenter(direction: 'left' | 'right') {
      if (props.disabled) return
      if (direction === 'left') {
        quickPrevHover.value = true
      } else {
        quickNextHover.value = true
      }
    }

    function onEnter(e: UIEvent) {
      const target = e.target as HTMLElement
      if (
        target.tagName.toLowerCase() === 'li' &&
        Array.from(target.classList).includes('number')
      ) {
        const newPage = Number(target.textContent)
        if (newPage !== props.currentPage) {
          emit('change', newPage)
        }
      }
    }

    function onPagerClick(event: UIEvent) {
      const target = event.target as HTMLElement
      if (target.tagName.toLowerCase() === 'ul' || props.disabled) {
        return
      }

      let newPage = Number(target.textContent)
      const pageCount = props.pageCount
      const currentPage = props.currentPage
      const pagerCountOffset = props.pagerCount - 2
      if (target.className.includes('more')) {
        if (target.className.includes('quickprev')) {
          newPage = currentPage - pagerCountOffset
        } else if (target.className.includes('quicknext')) {
          newPage = currentPage + pagerCountOffset
        }
      }
      if (!isNaN(newPage)) {
        if (newPage < 1) {
          newPage = 1
        }
        if (newPage > pageCount) {
          newPage = pageCount
        }
      }
      if (newPage !== currentPage) {
        emit('change', newPage)
      }
    }

    return {
      showPrevMore,
      showNextMore,
      quickPrevHover,
      quickNextHover,
      pagers,
      nsPager,
      nsIcon,

      onMouseenter,
      onPagerClick,
      onEnter,
    }
  },
})
</script>
