<template>
  <section class="page-card">
    <div class="hero">
      <h2>所有商品</h2>
      <div class="filters">
        <button
          v-for="opt in VIEW_OPTIONS"
          :key="opt.value"
          class="filter-btn"
          :class="{ active: viewMode === opt.value }"
          type="button"
          @click="setViewMode(opt.value)"
        >
          {{ opt.label }}
        </button>
      </div>
      <input
        v-model="searchQuery"
        class="search-input"
        type="text"
        placeholder="搜索商品/标签"
      />
    </div>

    <div v-if="loading" class="status">加载中...</div>
    <div v-else>
      <div class="grid">
        <ProductCard
          v-for="item in pagedProducts"
          :key="item.id"
          :item="item"
          @click="handleCardClick"
        />
      </div>

      <div class="pagination" v-if="totalPages > 1">
        <button class="ghost pg-btn" :disabled="page === 1" @click="page = 1">首页</button>
        <button class="ghost pg-btn" :disabled="page === 1" @click="page--">上一页</button>
        <span class="pg-info">第 {{ page }} / {{ totalPages }} 页</span>
        <button class="ghost pg-btn" :disabled="page === totalPages" @click="page++">下一页</button>
        <button class="ghost pg-btn" :disabled="page === totalPages" @click="page = totalPages">末页</button>
      </div>
    </div>
  </section>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { fetchProducts } from '../shared/api'
import ProductCard from './components/ProductCard.vue'

const router = useRouter()

const VIEW_OPTIONS = [
  { value: 'all', label: '全部' },
  { value: 'free', label: '免费' },
  { value: 'newest', label: '新上架' },
  { value: 'most-sold', label: '最多购买' },
  { value: 'most-viewed', label: '最多浏览' },
  { value: 'price-high', label: '价格最高' },
  { value: 'price-low', label: '价格最低' }
]

const products = ref([])
const loading = ref(true)
const page = ref(1)
const perPage = ref(20)
const viewMode = ref('all')
const searchQuery = ref('')

const updatePerPage = () => {
  perPage.value = window.innerWidth <= 900 ? 10 : 20
  page.value = 1
}

const getPayPrice = (item) => {
  if (!item) return 0
  // 折扣规则：discountPrice > 0 且小于原价时启用，price = 0 时显示"免费"
  if (item.price === 0) return 0
  if (item.discountPrice > 0 && item.discountPrice < item.price) return item.discountPrice
  return item.price
}

const isFree = (item) => getPayPrice(item) === 0
const isSoldOut = (item) => item && item.quantity === 0

const matchesSearch = (item) => {
  const q = (searchQuery.value || '').trim().toLowerCase()
  if (!q) return true
  const name = (item?.name || '').toLowerCase()
  const tags = (item?.tags || []).join(',').toLowerCase()
  return name.includes(q) || tags.includes(q)
}

const filteredProducts = computed(() => {
  let list = [...products.value]

  if (viewMode.value === 'free') list = list.filter((p) => isFree(p))

  if ((searchQuery.value || '').trim()) list = list.filter((p) => matchesSearch(p))

  switch (viewMode.value) {
    case 'newest':
      list.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))
      break
    case 'most-sold':
      list.sort((a, b) => (b.totalSold || 0) - (a.totalSold || 0))
      break
    case 'most-viewed':
      list.sort((a, b) => (b.viewCount || 0) - (a.viewCount || 0))
      break
    case 'price-high':
      list.sort((a, b) => getPayPrice(b) - getPayPrice(a))
      break
    case 'price-low':
      list.sort((a, b) => getPayPrice(a) - getPayPrice(b))
      break
    default:
      break
  }

  return list
})

const totalPages = computed(() =>
  Math.max(1, Math.ceil(filteredProducts.value.length / perPage.value))
)

const pagedProducts = computed(() => {
  const start = (page.value - 1) * perPage.value
  return filteredProducts.value.slice(start, start + perPage.value)
})

const handleCardClick = (item) => {
  if (!item || isSoldOut(item)) return
  router.push(`/product/${item.id}`)
}

const setViewMode = (next) => {
  viewMode.value = next
  page.value = 1
}

onMounted(async () => {
  updatePerPage()
  window.addEventListener('resize', updatePerPage)
  try {
    products.value = await fetchProducts()
  } finally {
    loading.value = false
  }
})

watch(viewMode, () => { page.value = 1 })
watch(searchQuery, () => { page.value = 1 })

onUnmounted(() => {
  window.removeEventListener('resize', updatePerPage)
})
</script>

<style scoped>
.hero {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.filters {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.search-input {
  width: 320px;
  max-width: 100%;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.7);
  padding: 10px 14px;
  font-family: 'KaiTi', 'STKaiti', '楷体', '楷体_GB2312', serif;
  font-size: 16px;
  outline: none;
}

.search-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(180, 154, 203, 0.18);
}

.filter-btn {
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.6);
  color: var(--text);
  font-size: 15px;
  font-weight: 700;
  transition: background 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.filter-btn:hover {
  transform: translateY(-1px);
}

.filter-btn.active {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border-color: transparent;
  color: #fff;
  box-shadow: 0 10px 30px rgba(145, 168, 208, 0.35);
}

.status {
  padding: 24px 0;
  color: var(--muted);
}

.tag {
  font-size: 14px;
  color: var(--muted);
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 22px;
  flex-wrap: wrap;
}

.pg-btn {
  padding: 6px 14px;
  font-size: 14px;
  border-radius: 999px;
  min-width: 60px;
}

.pg-btn:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

.pg-info {
  font-size: 14px;
  color: var(--muted);
  padding: 0 6px;
}

@media (max-width: 900px) {
  .hero {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 12px;
  }

  .hero h2 {
    font-size: 20px;
  }

  /* Filter buttons: scrollable horizontal row, no wrap */
  .filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 8px;
    width: 100%;
    padding-bottom: 4px;
    scrollbar-width: none;
  }

  .filters::-webkit-scrollbar {
    display: none;
  }

  .filter-btn {
    flex-shrink: 0;
    padding: 6px 10px;
    font-size: 13px;
  }

  .search-input {
    width: 100%;
    font-size: 14px;
    padding: 8px 12px;
  }
}
</style>
