<script lang="ts" setup>
import { computed, defineComponent, toRefs, watchEffect } from 'vue'
import { CHANGE_EVENT, PREFIX, UPDATE_MODEL_EVENT } from '../_constants'
import { getMainClass } from '../_utils'
import { useTranslate } from '../../locale'
import { paginationEmits, paginationProps } from './pagination'

const props = defineProps(paginationProps)
const emit = defineEmits(paginationEmits)
const { modelValue, mode, showPageSize, forceEllipses } = toRefs(props)
const classes = computed(() => {
  return getMainClass(props, componentName)
})
// 计算页面的数量
const countRef = computed(() => {
  const { pageCount, totalItems, itemsPerPage } = toRefs(props)
  const num = +pageCount.value || Math.ceil(+totalItems.value / +itemsPerPage.value)
  return Math.max(1, num)
})

// 点击选择page
function select(curPage: number, isSelect: boolean) {
  if (curPage > countRef.value || curPage < 1)
    return
  if (curPage !== modelValue.value)
    emit(UPDATE_MODEL_EVENT, curPage)
  if (isSelect)
    emit(CHANGE_EVENT, curPage)
}
// set page 对象
function setPage(number: number, text: string | number, active = false) {
  return { number, text, active }
}
// 生成pages数组，用来遍历
const pages = computed(() => {
  if (mode.value === 'simple')
    return
  const items = []
  const pageCount = countRef.value // 总的页面数量
  const pageSize = +showPageSize.value // 展示的页面个数
  let startPage = 1
  let endPage = pageCount
  const partialShow = pageCount > pageSize
  if (partialShow) {
    // 选中的page在展示的page中间
    startPage = Math.max(modelValue.value - Math.floor(pageSize / 2), 1)
    endPage = startPage + +pageSize - 1
    if (endPage > pageCount) {
      endPage = pageCount
      startPage = endPage - +pageSize + 1
    }
  }
  // 遍历生成数组
  for (let i = startPage; i <= endPage; i++) {
    const page = setPage(i, i, modelValue.value === i)
    items.push(page)
  }
  // 判断是否有折叠
  if (partialShow && pageSize > 0 && forceEllipses.value) {
    if (startPage > 1) {
      const prevPage = setPage(startPage - 1, '...')
      items.unshift(prevPage)
    }
    if (endPage < pageCount) {
      const nextPage = setPage(endPage + 1, '...')
      items.push(nextPage)
    }
  }

  return items
})

// 监听选中的page变化
watchEffect(() => {
  select(modelValue.value, false)
})
</script>

<script lang="ts">
const componentName = `${PREFIX}-pagination`
const { translate } = useTranslate(componentName)

export default defineComponent({
  name: componentName,
  options: {
    virtualHost: true,
    addGlobalClass: true,
    styleIsolation: 'shared',
  },
})
</script>

<template>
  <view :class="classes" :style="customStyle">
    <view
      class="nut-pagination-prev"
      :class="[mode === 'multi' ? '' : 'simple-border', modelValue === 1 ? 'disabled' : '']"
      @click="select(modelValue - 1, true)"
    >
      <slot name="prevText">
        {{ prevText || translate('prev') }}
      </slot>
    </view>
    <view v-if="mode === 'multi'" class="nut-pagination-contain">
      <view
        v-for="(item, index) of pages"
        :key="`${index}pagination`"
        class="nut-pagination-item"
        :class="[item.active ? 'active' : '']"
        @click="select(item.number, true)"
      >
        <slot name="page" :item="item">
          {{ item.text }}
        </slot>
      </view>
    </view>
    <view v-if="mode === 'simple'" class="nut-pagination-contain">
      <view class="nut-pagination-simple">
        {{ modelValue }}/{{ countRef }}
      </view>
    </view>
    <view
      class="nut-pagination-next"
      :class="[modelValue >= countRef ? 'disabled' : '']"
      @click="select(modelValue + 1, true)"
    >
      <slot name="nextText">
        {{ nextText || translate('next') }}
      </slot>
    </view>
  </view>
</template>

<style lang="scss">
@import './index';
</style>
