<template>
  <view class="card-detail-page">
    <!-- Loading state -->
    <view v-if="loading" class="loading-wrap">
      <view class="skeleton-header" />
      <view class="skeleton-body">
        <view class="skeleton-line w80" />
        <view class="skeleton-line w60" />
        <view class="skeleton-line w40" />
      </view>
    </view>

    <!-- Error state -->
    <view v-else-if="!card" class="error-wrap">
      <text class="error-icon">😕</text>
      <text class="error-text">会员卡信息加载失败</text>
      <view class="retry-btn" @tap="loadCard">
        <text class="retry-text">点击重试</text>
      </view>
    </view>

    <!-- Card content -->
    <template v-else>
      <!-- Hero section -->
      <view class="card-hero" :class="heroClass">
        <!-- Decorative circles -->
        <view class="hero-deco hero-deco--1" />
        <view class="hero-deco hero-deco--2" />

        <view class="hero-badge">
          <text class="hero-badge-text">{{ typeLabel }}</text>
        </view>
        <text class="hero-name">{{ card.name }}</text>
        <view class="hero-price-row">
          <text class="hero-currency">¥</text>
          <text class="hero-price">{{ formatPrice(card.price) }}</text>
          <text
            v-if="card.originalPrice && card.originalPrice > card.price"
            class="hero-original"
          >
            ¥{{ formatPrice(card.originalPrice) }}
          </text>
        </view>
      </view>

      <!-- Detail cards -->
      <view class="detail-section">
        <!-- Key info grid -->
        <view class="info-card">
          <view class="info-grid">
            <view class="info-cell" v-if="card.totalTimes">
              <text class="cell-value">{{ card.totalTimes }}</text>
              <text class="cell-label">课时次数</text>
            </view>
            <view class="info-cell">
              <text class="cell-value">{{ card.durationDays }}</text>
              <text class="cell-label">有效天数</text>
            </view>
            <view class="info-cell">
              <text class="cell-value">{{ unitPrice }}</text>
              <text class="cell-label">{{ card.totalTimes ? '每次单价' : '按天均价' }}</text>
            </view>
          </view>
        </view>

        <!-- Description -->
        <view v-if="card.description" class="desc-card">
          <view class="section-header">
            <view class="section-dot" />
            <text class="section-title">课程说明</text>
          </view>
          <text class="desc-content">{{ card.description }}</text>
        </view>

        <!-- Features list -->
        <view class="features-card">
          <view class="section-header">
            <view class="section-dot" />
            <text class="section-title">购买须知</text>
          </view>
          <view class="feature-item">
            <text class="feature-dot">•</text>
            <text class="feature-text">购买后立即生效，有效期 {{ card.durationDays }} 天</text>
          </view>
          <view v-if="card.totalTimes" class="feature-item">
            <text class="feature-dot">•</text>
            <text class="feature-text">共 {{ card.totalTimes }} 次课时，可灵活安排上课时间</text>
          </view>
          <view v-if="!card.totalTimes" class="feature-item">
            <text class="feature-dot">•</text>
            <text class="feature-text">有效期内可无限次预约课程</text>
          </view>
          <view class="feature-item">
            <text class="feature-dot">•</text>
            <text class="feature-text">每次预约扣除 1 次课时（次卡）</text>
          </view>
          <view class="feature-item">
            <text class="feature-dot">•</text>
            <text class="feature-text">到期或课时用完后自动失效，不可退款</text>
          </view>
          <view class="feature-item">
            <text class="feature-dot">•</text>
            <text class="feature-text">支持微信支付，安全便捷</text>
          </view>
        </view>
      </view>

      <!-- Bottom action bar -->
      <view class="bottom-bar">
        <view class="price-summary">
          <text class="summary-label">实付金额</text>
          <text class="summary-price">¥{{ formatPrice(card.price) }}</text>
        </view>
        <view
          class="buy-btn"
          :class="{ 'buy-btn--loading': buying }"
          @tap="handleBuy"
        >
          <text class="buy-btn-text">{{ buying ? '支付中...' : '立即购买' }}</text>
        </view>
      </view>
    </template>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { CardType, CreateOrderResponse } from '@mp-pilates/shared'
import { CardTypeCategory } from '@mp-pilates/shared'
import { get, post } from '../../utils/request'
import { formatPrice } from '../../utils/format'
import { useUserStore } from '../../stores/user'

const userStore = useUserStore()

// ─── Route params ──────────────────────────────────────────
const cardId = ref<string>('')
const isTrial = ref(false)

// ─── State ────────────────────────────────────────────────
const card = ref<CardType | null>(null)
const loading = ref(false)
const buying = ref(false)

// ─── Computed ─────────────────────────────────────────────
const typeLabel = computed(() => {
  if (!card.value) return ''
  const map: Record<CardTypeCategory, string> = {
    [CardTypeCategory.TIMES]: '次卡',
    [CardTypeCategory.DURATION]: '月卡',
    [CardTypeCategory.TRIAL]: '体验卡',
  }
  return map[card.value.type] ?? '会员卡'
})

const heroClass = computed(() => {
  if (!card.value) return ''
  if (card.value.type === CardTypeCategory.TRIAL) return 'hero--trial'
  if (card.value.type === CardTypeCategory.DURATION) return 'hero--duration'
  return 'hero--times'
})

const unitPrice = computed(() => {
  if (!card.value) return '-'
  if (card.value.totalTimes) {
    const pricePerTime = card.value.price / card.value.totalTimes
    return `¥${(pricePerTime / 100).toFixed(0)}`
  }
  const pricePerDay = card.value.price / card.value.durationDays
  return `¥${(pricePerDay / 100).toFixed(0)}`
})

// ─── Data loading ─────────────────────────────────────────
async function loadCard() {
  loading.value = true
  try {
    const types = await get<CardType[]>('/membership/card-types')
    const activeTypes = types.filter((c) => c.isActive)

    if (isTrial.value) {
      // Auto-find the trial card type
      card.value = activeTypes.find((c) => c.type === CardTypeCategory.TRIAL) ?? null
      if (card.value) {
        cardId.value = card.value.id
      }
    } else if (cardId.value) {
      card.value = activeTypes.find((c) => c.id === cardId.value) ?? null
    }
  } catch {
    card.value = null
  } finally {
    loading.value = false
  }
}

// ─── Buy flow ─────────────────────────────────────────────
async function handleBuy() {
  if (buying.value || !card.value) return

  // Ensure logged in
  if (!userStore.loggedIn) {
    uni.showModal({
      title: '提示',
      content: '请先登录后再购买会员卡',
      confirmText: '去登录',
      success: async (res) => {
        if (res.confirm) {
          try {
            await userStore.login()
            handleBuy()
          } catch {
            uni.showToast({ title: '登录失败', icon: 'none' })
          }
        }
      },
    })
    return
  }

  uni.showModal({
    title: '确认购买',
    content: `确认购买「${card.value.name}」，实付 ¥${formatPrice(card.value.price)}？`,
    confirmText: '确认支付',
    success: async (res) => {
      if (!res.confirm) return
      await doPurchase()
    },
  })
}

async function doPurchase() {
  if (!card.value) return
  buying.value = true
  uni.showLoading({ title: '创建订单...' })

  try {
    const result = await post<CreateOrderResponse>('/payment/create-order', {
      cardTypeId: card.value.id,
    })

    uni.hideLoading()

    // Launch WeChat Pay
    await new Promise<void>((resolve, reject) => {
      uni.requestPayment({
        provider: 'wxpay',
        timeStamp: result.paymentParams.timeStamp,
        nonceStr: result.paymentParams.nonceStr,
        package: result.paymentParams.package,
        signType: result.paymentParams.signType as 'MD5' | 'HMAC-SHA256',
        paySign: result.paymentParams.paySign,
        success: () => resolve(),
        fail: (err: { errMsg?: string }) => reject(new Error(err.errMsg ?? '支付取消')),
      })
    })

    // Payment succeeded — refresh memberships then navigate
    uni.showToast({ title: '购买成功！', icon: 'success' })
    await userStore.fetchMemberships()
    setTimeout(() => {
      uni.navigateTo({ url: '/pages/profile/membership' })
    }, 1500)
  } catch (err: unknown) {
    uni.hideLoading()
    const msg = err instanceof Error ? err.message : '支付失败，请重试'
    if (!msg.includes('取消') && !msg.includes('cancel')) {
      uni.showToast({ title: msg, icon: 'none' })
    }
  } finally {
    buying.value = false
  }
}

// ─── Lifecycle ────────────────────────────────────────────
onMounted(() => {
  const pages = getCurrentPages()
  const current = pages[pages.length - 1]
  const options = (current as { options?: Record<string, string> }).options ?? {}
  cardId.value = options.id ?? ''
  isTrial.value = options.trial === '1'
  loadCard()
})
</script>

<style lang="scss" scoped>
.card-detail-page {
  min-height: 100vh;
  background: #f5f3f0;
  padding-bottom: calc(160rpx + env(safe-area-inset-bottom));
}

/* ── Loading ─────────────────────────────────────────── */
.loading-wrap {
  padding: 0 0 32rpx;
}

.skeleton-header {
  height: 380rpx;
  background: linear-gradient(90deg, #e8e8e8 25%, #d8d8d8 50%, #e8e8e8 75%);
  background-size: 400% 100%;
  animation: shimmer 1.4s infinite;
}

.skeleton-body {
  padding: 32rpx 24rpx;
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

.skeleton-line {
  height: 28rpx;
  border-radius: 14rpx;
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 400% 100%;
  animation: shimmer 1.4s infinite;

  &.w80 { width: 80%; }
  &.w60 { width: 60%; }
  &.w40 { width: 40%; }
}

@keyframes shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

/* ── Error ───────────────────────────────────────────── */
.error-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 160rpx 40rpx;
  gap: 24rpx;
}

.error-icon {
  font-size: 80rpx;
}

.error-text {
  font-size: 30rpx;
  color: #999;
}

.retry-btn {
  padding: 20rpx 48rpx;
  border-radius: 40rpx;
  background: #c9a87c;
}

.retry-text {
  font-size: 28rpx;
  color: #fff;
  font-weight: 600;
}

/* ── Hero ────────────────────────────────────────────── */
.card-hero {
  padding: 64rpx 36rpx 56rpx;
  display: flex;
  flex-direction: column;
  gap: 18rpx;
  position: relative;
  overflow: hidden;

  &.hero--times {
    background: linear-gradient(135deg, #1a1a2e 0%, #2d2d5e 100%);
  }

  &.hero--duration {
    background: linear-gradient(135deg, #6c3483 0%, #9b59b6 100%);
  }

  &.hero--trial {
    background: linear-gradient(135deg, #7d6608 0%, #c9a87c 100%);
  }
}

/* Decorative background circles */
.hero-deco {
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.05);
  pointer-events: none;

  &--1 {
    width: 320rpx;
    height: 320rpx;
    top: -80rpx;
    right: -60rpx;
  }

  &--2 {
    width: 200rpx;
    height: 200rpx;
    bottom: -40rpx;
    left: 20rpx;
  }
}

.hero-badge {
  align-self: flex-start;
  padding: 8rpx 22rpx;
  border-radius: 20rpx;
  background: rgba(255, 255, 255, 0.18);
  border: 1rpx solid rgba(255, 255, 255, 0.3);
  z-index: 1;
}

.hero-badge-text {
  font-size: 22rpx;
  color: #fff;
  font-weight: 600;
  letter-spacing: 1rpx;
}

.hero-name {
  font-size: 48rpx;
  font-weight: 800;
  color: #fff;
  letter-spacing: 1rpx;
  z-index: 1;
}

.hero-price-row {
  display: flex;
  align-items: baseline;
  gap: 8rpx;
  z-index: 1;
}

.hero-currency {
  font-size: 28rpx;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
  line-height: 1;
}

.hero-price {
  font-size: 64rpx;
  font-weight: 800;
  color: #fff;
  line-height: 1;
}

.hero-original {
  font-size: 28rpx;
  color: rgba(255, 255, 255, 0.5);
  text-decoration: line-through;
  margin-left: 8rpx;
}

/* ── Detail section ──────────────────────────────────── */
.detail-section {
  padding: 24rpx 24rpx 0;
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

/* ── Section header ──────────────────────────────────── */
.section-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12rpx;
  margin-bottom: 16rpx;
}

.section-dot {
  width: 6rpx;
  height: 28rpx;
  border-radius: 3rpx;
  background: #c9a87c;
  flex-shrink: 0;
}

.section-title {
  font-size: 30rpx;
  font-weight: 700;
  color: #1a1a1a;
}

/* ── Info grid card ──────────────────────────────────── */
.info-card {
  background: #fff;
  border-radius: 20rpx;
  padding: 32rpx 24rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}

.info-grid {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
}

.info-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8rpx;
  flex: 1;
  position: relative;

  & + & {
    border-left: 1rpx solid #f0f0f0;
  }
}

.cell-value {
  font-size: 44rpx;
  font-weight: 800;
  color: #1a1a1a;
  line-height: 1.1;
}

.cell-label {
  font-size: 22rpx;
  color: #999;
}

/* ── Description card ────────────────────────────────── */
.desc-card {
  background: #fff;
  border-radius: 20rpx;
  padding: 28rpx 24rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}

.desc-content {
  font-size: 27rpx;
  color: #666;
  line-height: 1.75;
}

/* ── Features card ───────────────────────────────────── */
.features-card {
  background: #fff;
  border-radius: 20rpx;
  padding: 28rpx 24rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
}

.feature-item {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 12rpx;
  padding: 6rpx 0;
}

.feature-dot {
  font-size: 26rpx;
  color: #c9a87c;
  line-height: 1.65;
  flex-shrink: 0;
}

.feature-text {
  font-size: 26rpx;
  color: #555;
  line-height: 1.65;
}

/* ── Bottom action bar ───────────────────────────────── */
.bottom-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
  border-top: 1rpx solid #f0ece8;
  padding: 20rpx 32rpx calc(20rpx + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 24rpx;
  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
}

.price-summary {
  display: flex;
  flex-direction: column;
  gap: 4rpx;
}

.summary-label {
  font-size: 22rpx;
  color: #999;
}

.summary-price {
  font-size: 40rpx;
  font-weight: 800;
  color: #c9a87c;
}

.buy-btn {
  flex: 1;
  height: 88rpx;
  border-radius: 44rpx;
  background: linear-gradient(90deg, #1a1a2e, #2d2d5e);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4rpx 16rpx rgba(26, 26, 46, 0.3);

  &:active {
    opacity: 0.85;
  }

  &--loading {
    opacity: 0.6;
  }
}

.buy-btn-text {
  font-size: 32rpx;
  font-weight: 700;
  color: #c9a87c;
  letter-spacing: 2rpx;
}
</style>
