<script setup lang="ts">
/**
 * 抢购活动详情
 *
 * 活动倒计时 + 抢购商品列表（价格、库存进度、限购、立即抢购）
 */
import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowLeft, Clock, Lightning, Minus, Plus } from '@element-plus/icons-vue'
import AppHeader from '@/components/layout/AppHeader.vue'
import AppFooter from '@/components/layout/AppFooter.vue'
import EmptyState from '@/components/common/EmptyState.vue'
import Countdown from '@/components/seckill/Countdown.vue'
import { getSeckillDetailApi, seckillBuyApi } from '@/api/seckill'
import { useUserStore } from '@/stores/modules/user'
import type { SeckillActivity, SeckillProduct } from '@/types/seckill'

const route = useRoute()
const router = useRouter()
const userStore = useUserStore()

const activity = ref<SeckillActivity | null>(null)
const loading = ref(true)
const buyingSkuId = ref<number | null>(null)
const quantities = ref<Record<number, number>>({})

async function loadDetail() {
  const id = Number(route.params.id)
  if (!id || Number.isNaN(id)) {
    router.replace('/404')
    return
  }

  loading.value = true
  try {
    activity.value = await getSeckillDetailApi(id)
    document.title = activity.value?.name
      ? `${activity.value.name} - 零食商城`
      : '抢购详情 - 零食商城'
    const map: Record<number, number> = {}
    activity.value?.products?.forEach(product => {
      map[product.skuId] = 1
    })
    quantities.value = map
  } catch {
    activity.value = null
  } finally {
    loading.value = false
  }
}

function handleExpire() {
  loadDetail()
}

function canBuy(product: SeckillProduct) {
  return activity.value?.status === 1 && product.remainStock > 0
}

function stateText(product: SeckillProduct) {
  if (activity.value?.status === 0) return '活动未开始'
  if (activity.value?.status === 2) return '活动已结束'
  if (product.remainStock <= 0) return '已抢完'
  return ''
}

function changeQty(product: SeckillProduct, delta: number) {
  const current = quantities.value[product.skuId] || 1
  const next = current + delta
  const max = Math.min(product.perLimit || 1, Math.max(product.remainStock, 1))
  if (next < 1) return
  if (next > max) {
    ElMessage.warning(`每人限购 ${product.perLimit} 件`)
    return
  }
  quantities.value = { ...quantities.value, [product.skuId]: next }
}

async function handleBuy(product: SeckillProduct) {
  if (!activity.value || !canBuy(product)) return

  if (!userStore.isLoggedIn) {
    router.push(`/login?redirect=${encodeURIComponent(route.fullPath)}`)
    return
  }

  buyingSkuId.value = product.skuId
  try {
    const data = await seckillBuyApi({
      activityId: activity.value.id,
      skuId: product.skuId,
      quantity: quantities.value[product.skuId] || 1
    })
    await ElMessageBox.alert(
      `抢购成功，排队号：${data.orderNo}。请及时前往订单页完成支付。`,
      '抢购成功',
      { confirmButtonText: '知道了' }
    )
    await loadDetail()
  } catch {
    /* 拦截器已提示 */
  } finally {
    buyingSkuId.value = null
  }
}

function formatPrice(value: number | string | null | undefined) {
  return Number(value || 0).toFixed(2)
}

function formatTime(value?: string) {
  return value ? value.slice(0, 16) : ''
}

onMounted(loadDetail)
</script>

<template>
  <div class="seckill-detail-page">
    <AppHeader />

    <main class="detail-main">
      <div class="container">
        <el-skeleton v-if="loading" :rows="6" animated class="detail-skeleton" />

        <template v-else-if="activity">
          <button type="button" class="back-btn" @click="router.push('/seckill')">
            <el-icon :size="15"><ArrowLeft /></el-icon>
            限时抢购
          </button>

          <div class="activity-head" :class="`status-${activity.status}`">
            <div class="head-left">
              <div class="title-row">
                <h1 class="activity-name">{{ activity.name }}</h1>
                <span class="status-badge" :class="`badge-${activity.status}`">
                  {{ activity.statusText }}
                </span>
              </div>

              <p class="time-range">
                <el-icon :size="16"><Clock /></el-icon>
                {{ formatTime(activity.startTime) }} ~ {{ formatTime(activity.endTime) }}
              </p>
              <p v-if="activity.description" class="description">{{ activity.description }}</p>
            </div>

            <div class="head-countdown">
              <span class="countdown-label">
                {{ activity.status === 0 ? '距开始' : activity.status === 1 ? '距结束' : '已结束' }}
              </span>
              <Countdown
                v-if="activity.status !== 2"
                :seconds="activity.countdownSeconds"
                @expire="handleExpire"
              />
              <span v-else class="ended-text">已结束</span>
            </div>
          </div>

          <section class="product-section">
            <div class="section-head">
              <h2 class="section-title">活动商品</h2>
              <span class="section-count">{{ activity.products?.length || 0 }} 件</span>
            </div>

            <EmptyState
              v-if="!activity.products?.length"
              description="本场活动暂无商品"
            />

            <div v-else class="product-grid">
              <div
                v-for="product in activity.products"
                :key="product.skuId"
                class="product-card"
                :class="{ soldout: product.remainStock <= 0 }"
              >
                <div class="product-image" @click="router.push(`/product/${product.productId}`)">
                  <el-image
                    :src="product.productImage"
                    fit="cover"
                    class="product-img"
                    lazy
                  >
                    <template #error>
                      <div class="image-placeholder">
                        <el-icon :size="36"><Lightning /></el-icon>
                      </div>
                    </template>
                  </el-image>
                  <span v-if="product.discount" class="discount-badge">
                    {{ product.discount }}折
                  </span>
                </div>

                <div class="product-body">
                  <h3 class="product-name" @click="router.push(`/product/${product.productId}`)">
                    {{ product.productName }}
                  </h3>
                  <p class="sku-name">{{ product.skuName }}</p>

                  <div class="price-row">
                    <span class="seckill-price">¥{{ formatPrice(product.seckillPrice) }}</span>
                    <span class="origin-price">¥{{ formatPrice(product.originPrice) }}</span>
                  </div>

                  <div class="stock-row">
                    <div class="progress-track">
                      <div
                        class="progress-fill"
                        :style="{ width: `${Math.min(product.soldPercent, 100)}%` }"
                      />
                    </div>
                    <span class="sold-text">已抢 {{ product.soldPercent }}%</span>
                  </div>

                  <div class="stock-meta">
                    <span v-if="product.remainStock > 0" class="remain-text">
                      仅剩 {{ product.remainStock }} 件
                    </span>
                    <span v-else class="soldout-text">已抢完</span>
                    <span class="limit-text">每人限购 {{ product.perLimit }} 件</span>
                  </div>

                  <div v-if="canBuy(product)" class="buy-row">
                    <div class="qty-stepper">
                      <button
                        type="button"
                        class="qty-btn"
                        :disabled="(quantities[product.skuId] || 1) <= 1"
                        @click="changeQty(product, -1)"
                      >
                        <el-icon :size="14"><Minus /></el-icon>
                      </button>
                      <span class="qty-num">{{ quantities[product.skuId] || 1 }}</span>
                      <button
                        type="button"
                        class="qty-btn"
                        :disabled="(quantities[product.skuId] || 1) >= Math.min(product.perLimit, Math.max(product.remainStock, 1))"
                        @click="changeQty(product, 1)"
                      >
                        <el-icon :size="14"><Plus /></el-icon>
                      </button>
                    </div>

                    <button
                      type="button"
                      class="buy-btn"
                      :disabled="buyingSkuId === product.skuId"
                      @click="handleBuy(product)"
                    >
                      <el-icon :size="15"><Lightning /></el-icon>
                      {{ buyingSkuId === product.skuId ? '抢购中...' : '立即抢购' }}
                    </button>
                  </div>

                  <span v-else class="state-text">{{ stateText(product) }}</span>
                </div>
              </div>
            </div>
          </section>
        </template>

        <EmptyState v-else description="活动不存在或已结束" />
      </div>
    </main>

    <AppFooter />
  </div>
</template>

<style lang="scss" scoped>
.seckill-detail-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: $bg-page;
}

.detail-main {
  flex: 1;
  padding: 28px 0 48px;
}

.container {
  max-width: $container-max;
  margin: 0 auto;
  padding: 0 24px;
}

.detail-skeleton {
  padding: 20px;
  border: 2px solid $color-border;
  border-radius: $radius-lg;
  background: $bg-surface;
  box-shadow: $clay-shadow-sm;
}

// ==================== 返回 ====================
.back-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  margin-bottom: 18px;
  border: 2px solid $color-border;
  border-radius: $radius-full;
  background: $bg-surface;
  color: $color-text-regular;
  font-size: $font-size-sm;
  font-weight: 600;
  box-shadow: 0 2px 0 0 $color-border-dark;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, transform 0.2s;

  &:hover {
    color: $color-primary;
    border-color: $color-primary;
    transform: translateY(-1px);
  }
}

// ==================== 活动头部 ====================
.activity-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding: 24px;
  margin-bottom: 28px;
  background: $bg-surface;
  border: 2px solid $color-border;
  border-radius: $radius-lg;
  box-shadow: $clay-shadow-sm;
}

.head-left {
  flex: 1;
  min-width: 260px;
}

.title-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.activity-name {
  margin: 0;
  font-size: $font-size-xxl;
  font-weight: 700;
  color: $color-text-primary;
}

.status-badge {
  padding: 4px 14px;
  border-radius: $radius-full;
  font-size: $font-size-sm;
  font-weight: 700;
  line-height: 1.5;

  &.badge-0 {
    background: #FEF3C7;
    color: $color-warning;
  }

  &.badge-1 {
    background: $color-primary-light;
    color: $color-primary;
  }

  &.badge-2 {
    background: $bg-hover;
    color: $color-text-secondary;
  }
}

.time-range {
  margin: 0 0 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: $font-size-sm;
  color: $color-text-secondary;
}

.description {
  margin: 0;
  font-size: $font-size-sm;
  color: $color-text-secondary;
  line-height: 1.6;
}

.head-countdown {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  padding: 14px 18px;
  border: 2px solid $color-border;
  border-radius: $radius-md;
  background: $color-primary-light;

  .countdown-label {
    font-size: $font-size-sm;
    color: $color-text-secondary;
  }
}

.ended-text {
  font-size: $font-size-lg;
  font-weight: 700;
  color: $color-text-placeholder;
}

// ==================== 商品区 ====================
.section-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 20px;
}

.section-title {
  margin: 0;
  font-size: $font-size-xl;
  font-weight: 700;
  color: $color-text-primary;
}

.section-count {
  font-size: $font-size-sm;
  color: $color-text-secondary;
}

.product-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.product-card {
  display: flex;
  flex-direction: column;
  background: $bg-surface;
  border: 2px solid $color-border;
  border-radius: $radius-lg;
  box-shadow: $clay-shadow-sm;
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease, opacity 0.2s;

  &:hover {
    transform: translateY(-4px);
    box-shadow: $clay-shadow-md;
  }

  &.soldout {
    opacity: 0.78;
  }
}

.product-image {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: $bg-page;
  cursor: pointer;

  .product-img {
    width: 100%;
    height: 100%;
  }

  .image-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: $color-primary;
  }
}

.discount-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  padding: 3px 10px;
  border-radius: $radius-full;
  background: linear-gradient(135deg, $color-primary, $color-cta);
  color: #fff;
  font-size: $font-size-xs;
  font-weight: 700;
  line-height: 1.4;
}

.product-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
}

.product-name {
  margin: 0;
  font-size: $font-size-lg;
  font-weight: 600;
  color: $color-text-primary;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  cursor: pointer;
  transition: color 0.2s;

  &:hover {
    color: $color-primary;
  }
}

.sku-name {
  margin: 0;
  font-size: $font-size-sm;
  color: $color-text-secondary;
}

.price-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.seckill-price {
  font-family: 'Fredoka', sans-serif;
  font-size: $font-size-xl;
  font-weight: 700;
  color: $color-primary;
}

.origin-price {
  font-size: $font-size-sm;
  color: $color-text-placeholder;
  text-decoration: line-through;
}

.stock-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.progress-track {
  flex: 1;
  height: 8px;
  border-radius: $radius-full;
  background: $bg-hover;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  border-radius: $radius-full;
  background: linear-gradient(90deg, $color-secondary, $color-cta);
  transition: width 0.3s ease;
}

.sold-text {
  flex-shrink: 0;
  font-size: $font-size-xs;
  color: $color-text-secondary;
}

.stock-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.remain-text {
  font-size: $font-size-xs;
  color: $color-danger;
  font-weight: 600;
}

.soldout-text {
  font-size: $font-size-xs;
  color: $color-text-placeholder;
  font-weight: 600;
}

.limit-text {
  font-size: $font-size-xs;
  color: $color-text-placeholder;
}

.buy-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 2px;
}

.qty-stepper {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px;
  border: 2px solid $color-border;
  border-radius: $radius-full;
  background: $bg-page;
}

.qty-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: $radius-full;
  background: $bg-surface;
  color: $color-text-regular;
  cursor: pointer;
  transition: color 0.2s, background-color 0.2s;

  &:hover:not(:disabled) {
    color: $color-primary;
    background: $color-primary-light;
  }

  &:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }
}

.qty-num {
  min-width: 26px;
  text-align: center;
  font-size: $font-size-md;
  font-weight: 700;
  color: $color-text-primary;
  font-family: 'Fredoka', sans-serif;
}

.buy-btn {
  flex: 1;
  min-height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 2px solid $color-border-dark;
  border-radius: $radius-full;
  background: linear-gradient(135deg, $color-primary, $color-cta);
  color: #fff;
  font-size: $font-size-md;
  font-weight: 600;
  box-shadow: 0 4px 0 0 $color-primary-dark;
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s, filter 0.2s, opacity 0.2s;

  &:hover:not(:disabled) {
    filter: brightness(1.04);
    transform: translateY(-1px);
  }

  &:active:not(:disabled) {
    box-shadow: 0 1px 0 0 $color-primary-dark;
    transform: translateY(3px);
  }

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}

.state-text {
  display: block;
  padding: 11px 0;
  text-align: center;
  font-size: $font-size-md;
  font-weight: 600;
  color: $color-text-placeholder;
}

// ==================== 响应式 ====================
@media (max-width: 1024px) {
  .product-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .container {
    padding: 0 16px;
  }

  .activity-head {
    padding: 18px;
  }

  .activity-name {
    font-size: $font-size-xl;
  }

  .head-countdown {
    width: 100%;
    align-items: flex-start;
  }

  .product-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }
}
</style>
