<template>
  <!--
    通用分页器(F-260621-02 P3 分页 UI 基建)。
    纯客户端切片分页:父级传 total(总数) + v-model:page(当前页,1 起) +
    v-model:pageSize(每页条数),本组件只管 UI,不做数据请求(数据量 ~15 前瞻基建)。

    向后兼容铁律:pageSize=0 → 不分页(全量),整组件隐藏,等价改造前行为。
    用户从下拉选具体 N → 触发分页(切换 page 重置到第 1 页由父级 watch 控制)。
  -->
  <div v-if="pageSize > 0 && totalPages > 0" class="paginator">
    <div class="page-size-group">
      <span class="paginator-label">{{ $t('common.pagination.perPage') }}</span>
      <select
        class="page-size-select"
        :value="pageSize"
        @change="onPageSizeChange(($event.target as HTMLSelectElement).value)"
      >
        <option v-for="opt in pageSizeOptions" :key="opt" :value="opt">{{ opt }}</option>
      </select>
      <span class="paginator-total">
        {{ $t('common.pagination.total', { n: total }) }}
      </span>
    </div>

    <div class="page-nav">
      <button
        class="page-btn"
        :disabled="page <= 1"
        @click="goTo(page - 1)"
      >{{ $t('common.pagination.prev') }}</button>

      <button
        v-for="p in pageNumbers"
        :key="p"
        class="page-btn page-num"
        :class="{ active: p === page }"
        @click="goTo(p)"
      >{{ p }}</button>

      <button
        class="page-btn"
        :disabled="page >= totalPages"
        @click="goTo(page + 1)"
      >{{ $t('common.pagination.next') }}</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

const props = withDefaults(defineProps<{
  /** 数据总数(父级传当前过滤后的总数) */
  total: number
  /** 每页条数;0 = 不分页(整组件隐藏,等价旧行为) */
  pageSize: number
  /** 当前页码(1 起) */
  page: number
  /** 每页条数候选(默认 10/20/50) */
  pageSizeOptions?: number[]
}>(), {
  pageSizeOptions: () => [10, 20, 50],
})

const emit = defineEmits<{
  'update:page': [page: number]
  'update:pageSize': [size: number]
}>()

// 总页数:pageSize=0 已被 v-if 拦截,此处保证 pageSize ≥ 1。
const totalPages = computed(() => {
  if (props.pageSize <= 0) return 0
  return Math.max(1, Math.ceil(props.total / props.pageSize))
})

// 简单页码序列:数据量小,全列(1..totalPages),不做省略窗口(7 页内可读)。
// 若数据量未来增长到几十页,再加窗口折叠逻辑。
const pageNumbers = computed(() => {
  const arr: number[] = []
  for (let i = 1; i <= totalPages.value; i++) arr.push(i)
  return arr
})

function goTo(p: number) {
  if (p < 1 || p > totalPages.value) return
  emit('update:page', p)
}

function onPageSizeChange(val: string) {
  const n = Number(val)
  if (!Number.isFinite(n) || n < 0) return
  emit('update:pageSize', n)
  // 切换每页条数后页码可能越界,重置到第 1 页(父级也可自行 watch 处理)
  emit('update:page', 1)
}
</script>

<style scoped>
.paginator {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: var(--df-gap-grid, 16px);
  padding: 8px 4px;
  font-size: 12px;
  color: var(--df-text-dim);
}

.page-size-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

.paginator-label { white-space: nowrap; }

.page-size-select {
  padding: 3px 8px;
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-sm);
  background: var(--df-bg);
  color: var(--df-text);
  font-size: 12px;
  cursor: pointer;
}

.paginator-total { color: var(--df-text-dim); }

.page-nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.page-btn {
  min-width: 28px;
  padding: 3px 8px;
  border: 0.5px solid var(--df-border);
  border-radius: var(--df-radius-sm);
  background: transparent;
  color: var(--df-text-secondary);
  font-size: 12px;
  cursor: pointer;
  transition: all 0.15s;
}

.page-btn:hover:not(:disabled) {
  background: rgba(108, 99, 255, 0.06);
  color: var(--df-text);
}

.page-btn.active {
  background: var(--df-accent);
  color: #fff;
  border-color: var(--df-accent);
}

.page-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

@media (max-width: 600px) {
  .paginator { justify-content: center; }
}
</style>
