<script setup lang="ts">
const props = defineProps<{
  total: number;
  page: number;
  pageSize: number;
}>();

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

const totalPages = computed(() => {
  if (props.total <= 0) return 1;
  return Math.max(1, Math.ceil(props.total / props.pageSize));
});

const pageNumbers = computed<(number | string)[]>(() => {
  const total = totalPages.value;
  const current = props.page;
  if (total <= 7) {
    return Array.from({ length: total }, (_, i) => i + 1);
  }
  const pages: (number | string)[] = [1];
  const start = Math.max(2, current - 1);
  const end = Math.min(total - 1, current + 1);
  if (start > 2) pages.push('...');
  for (let i = start; i <= end; i++) pages.push(i);
  if (end < total - 1) pages.push('...');
  pages.push(total);
  return pages;
});

const canPrev = computed(() => props.page > 1);
const canNext = computed(() => props.page < totalPages.value);

const gotoInput = ref('');

function goPrev(): void {
  if (canPrev.value) emit('update:page', props.page - 1);
}

function goNext(): void {
  if (canNext.value) emit('update:page', props.page + 1);
}

function goToPage(page: number): void {
  if (page < 1 || page > totalPages.value || page === props.page) return;
  emit('update:page', page);
}

function onPageSizeChange(event: Event): void {
  const target = event.target as HTMLSelectElement;
  const size = Number(target.value);
  if (!Number.isFinite(size) || size <= 0) return;
  emit('update:pageSize', size);
}

function onGoto(): void {
  const value = Number(gotoInput.value);
  if (!Number.isFinite(value)) return;
  const clamped = Math.min(totalPages.value, Math.max(1, Math.floor(value)));
  gotoInput.value = '';
  goToPage(clamped);
}

function onGotoKeydown(event: KeyboardEvent): void {
  if (event.key === 'Enter') {
    event.preventDefault();
    onGoto();
  }
}
</script>

<template>
  <div class="pagination">
    <div class="total-text">
      总计 <span>{{ total }}</span> 个产品
    </div>

    <div class="page-buttons">
      <button
        type="button"
        class="nav-btn"
        :disabled="!canPrev"
        @click="goPrev"
      >
        <i class="fa-solid fa-chevron-left"></i>
      </button>
      <button
        v-for="(item, idx) in pageNumbers"
        :key="`page-${idx}-${item}`"
        type="button"
        class="page-btn"
        :class="{
          current: item === page,
          dots: item === '...',
        }"
        :disabled="item === '...'"
        @click="typeof item === 'number' && goToPage(item)"
      >
        {{ item }}
      </button>
      <button
        type="button"
        class="nav-btn"
        :disabled="!canNext"
        @click="goNext"
      >
        <i class="fa-solid fa-chevron-right"></i>
      </button>
    </div>

    <div class="right-controls">
      <select :value="pageSize" class="size-select" @change="onPageSizeChange">
        <option :value="12">12 / 页</option>
        <option :value="20">20 / 页</option>
        <option :value="40">40 / 页</option>
      </select>
      <span class="goto-label">导航至</span>
      <input
        v-model="gotoInput"
        type="number"
        min="1"
        :max="totalPages"
        class="goto-input"
        @keydown="onGotoKeydown"
      />
      <button type="button" class="goto-btn" @click="onGoto">Go</button>
    </div>
  </div>
</template>

<style scoped>
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  padding: 16px 24px;
  font-size: 14px;
  color: #777;
}

.total-text span {
  font-weight: 600;
  color: #222;
}

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

.nav-btn,
.page-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  border-radius: 6px;
  border: 1px solid #eee;
  background: #fff;
  color: #555;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s ease;
}

.nav-btn:hover:not(:disabled),
.page-btn:hover:not(.dots):not(.current) {
  border-color: #ff6a00;
  color: #ff6a00;
}

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

.page-btn.current {
  background: #ff6a00;
  border-color: #ff6a00;
  color: #fff;
}

.page-btn.dots {
  border-color: transparent;
  cursor: default;
}

.right-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.size-select {
  height: 32px;
  padding: 0 8px;
  border: 1px solid #eee;
  border-radius: 6px;
  background: #fff;
  font-size: 14px;
  color: #555;
  outline: none;
}

.goto-label {
  color: #999;
}

.goto-input {
  width: 48px;
  height: 32px;
  padding: 0 8px;
  border: 1px solid #eee;
  border-radius: 6px;
  background: #fff;
  font-size: 14px;
  color: #222;
  outline: none;
  text-align: center;
}

.goto-input:focus {
  border-color: #ff6a00;
}

.goto-btn {
  height: 32px;
  padding: 0 12px;
  border: 1px solid #ff6a00;
  border-radius: 6px;
  background: transparent;
  color: #ff6a00;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s ease;
}

.goto-btn:hover {
  background: #ff6a00;
  color: #fff;
}
</style>
