<template>
  <view class="membership-page" :style="{ paddingTop: navBarHeight }">
    <CustomNavBar title="我的会员卡" show-back />
    <scroll-view
      class="scroll"
      scroll-y
      refresher-enabled
      :refresher-triggered="refreshing"
      @refresherrefresh="onRefresh"
    >
      <!-- Loading skeleton -->
      <view v-if="loading && !refreshing" class="loading-wrap">
        <view v-for="i in 2" :key="i" class="skeleton-card" />
      </view>

      <!-- Empty state -->
      <view v-else-if="allMemberships.length === 0" class="empty-wrap">
        <view class="empty-card">
          <view class="empty-deco empty-deco--1" />
          <view class="empty-deco empty-deco--2" />
          <text class="empty-title">还没有会员卡</text>
          <text class="empty-sub">购买会员卡后即可预约课程</text>
          <view class="empty-btn" @tap="goStore">
            <text class="empty-btn-text">去选购</text>
          </view>
        </view>
      </view>

      <!-- Membership list -->
      <view v-else class="list">
        <!-- Active cards -->
        <view v-if="activeMemberships.length > 0" class="group-section">
          <view class="group-header">
            <text class="group-title">有效会员卡</text>
            <text class="group-count">{{ activeMemberships.length }} 张</text>
          </view>

          <view
            v-for="m in activeMemberships"
            :key="m.id"
            class="mc"
            :class="cardBgClass(m.cardType.type)"
          >
            <!-- Decorative circles -->
            <view class="mc-deco mc-deco--1" />
            <view class="mc-deco mc-deco--2" />

            <!-- Top row: name + status -->
            <view class="mc-top">
              <view class="mc-name-area">
                <text class="mc-name">{{ m.cardType.name }}</text>
                <view class="mc-type-tag">
                  <text class="mc-type-text">{{ getCardTypeLabel(m.cardType.type) }}</text>
                </view>
              </view>
              <view class="mc-status mc-status--active">
                <view class="mc-status-dot" />
                <text class="mc-status-text">有效</text>
              </view>
            </view>

            <!-- Center: highlight number (times card) -->
            <view v-if="m.remainingTimes !== null" class="mc-center">
              <text class="mc-big-num">{{ m.remainingTimes }}</text>
              <text class="mc-big-unit">次剩余</text>
              <view v-if="m.cardType.totalTimes" class="mc-progress">
                <view class="mc-progress-track">
                  <view
                    class="mc-progress-fill"
                    :style="{ width: getMembershipProgressWidth(m) }"
                  />
                </view>
                <text class="mc-progress-label">
                  已用 {{ getMembershipUsedTimes(m) }}，共 {{ m.cardType.totalTimes }} 次
                </text>
              </view>
            </view>

            <!-- Center: duration card (no times) -->
            <view v-else class="mc-center">
              <text class="mc-big-num">{{ daysRemaining(m) }}</text>
              <text class="mc-big-unit">天剩余</text>
            </view>

            <!-- Bottom: dates -->
            <view class="mc-bottom">
              <view class="mc-date-item">
                <text class="mc-date-label">开始</text>
                <text class="mc-date-value">{{ m.startDate.slice(0, 10) }}</text>
              </view>
              <view class="mc-date-sep" />
              <view class="mc-date-item">
                <text class="mc-date-label">到期</text>
                <text class="mc-date-value">{{ m.expireDate.slice(0, 10) }}</text>
              </view>
            </view>
          </view>
        </view>

        <!-- Expired / used up cards -->
        <view v-if="inactiveMemberships.length > 0" class="group-section">
          <view class="group-header">
            <text class="group-title">历史记录</text>
            <text class="group-count">{{ inactiveMemberships.length }} 张</text>
          </view>

          <view
            v-for="m in inactiveMemberships"
            :key="m.id"
            class="mc mc--inactive"
          >
            <view class="mc-deco mc-deco--1" />

            <view class="mc-top">
              <view class="mc-name-area">
                <text class="mc-name">{{ m.cardType.name }}</text>
                <view class="mc-type-tag">
                  <text class="mc-type-text">{{ getCardTypeLabel(m.cardType.type) }}</text>
                </view>
              </view>
              <view class="mc-status" :class="inactiveStatusClass(m.status)">
                <text class="mc-status-text">{{ statusLabel(m.status) }}</text>
              </view>
            </view>

            <view class="mc-inactive-info">
              <view v-if="m.remainingTimes !== null" class="mc-date-item">
                <text class="mc-date-label">剩余</text>
                <text class="mc-date-value">{{ m.remainingTimes }} 次</text>
              </view>
              <view class="mc-date-item">
                <text class="mc-date-label">有效期至</text>
                <text class="mc-date-value">{{ m.expireDate.slice(0, 10) }}</text>
              </view>
            </view>
          </view>
        </view>
      </view>

      <view class="scroll-bottom-spacer" />
    </scroll-view>

    <!-- Buy more FAB -->
    <view class="fab" @tap="goStore">
      <text class="fab-text">+ 购买会员卡</text>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { MembershipWithCardType } from '@mp-pilates/shared'
import { MembershipStatus, CardTypeCategory } from '@mp-pilates/shared'
import { useUserStore } from '../../stores/user'
import { getSystemLayout } from '../../utils/system'
import { getCardTypeLabel, getMembershipProgressWidth, getMembershipUsedTimes } from '../../utils/format'
import CustomNavBar from '../../components/CustomNavBar.vue'

const userStore = useUserStore()

const navBarHeight = ref('64px')
const loading = ref(false)
const refreshing = ref(false)

const allMemberships = computed(() => userStore.memberships as MembershipWithCardType[])

const activeMemberships = computed(() =>
  allMemberships.value.filter((m) => m.status === MembershipStatus.ACTIVE),
)

const inactiveMemberships = computed(() =>
  allMemberships.value.filter((m) => m.status !== MembershipStatus.ACTIVE),
)

function statusLabel(status: MembershipStatus): string {
  const map: Record<MembershipStatus, string> = {
    [MembershipStatus.ACTIVE]: '有效',
    [MembershipStatus.EXPIRED]: '已过期',
    [MembershipStatus.USED_UP]: '已用完',
  }
  return map[status] ?? status
}

function inactiveStatusClass(status: MembershipStatus): string {
  if (status === MembershipStatus.USED_UP) return 'mc-status--used'
  return 'mc-status--expired'
}

function cardBgClass(type: CardTypeCategory): string {
  if (type === CardTypeCategory.TRIAL) return 'mc--trial'
  if (type === CardTypeCategory.DURATION) return 'mc--duration'
  return 'mc--times'
}

function daysRemaining(m: MembershipWithCardType): number {
  const diff = new Date(m.expireDate).getTime() - Date.now()
  return Math.max(0, Math.ceil(diff / 86_400_000))
}

async function loadMemberships() {
  loading.value = true
  try {
    await userStore.fetchMemberships()
  } catch {
    uni.showToast({ title: '加载失败，请下拉刷新', icon: 'none' })
  } finally {
    loading.value = false
  }
}

async function onRefresh() {
  refreshing.value = true
  await userStore.fetchMemberships()
  refreshing.value = false
}

function goStore() {
  uni.switchTab({ url: '/pages/home/index' })
}

onMounted(() => {
  navBarHeight.value = `${getSystemLayout().navBarHeight}px`
  loadMemberships()
})
</script>

<style lang="scss" scoped>
.membership-page {
  min-height: 100vh;
  background: $bg-page;
}

.scroll {
  height: 100vh;
}

/* ── Loading ─────────────────────────────── */
.loading-wrap {
  padding: 24rpx;
  display: flex;
  flex-direction: column;
  gap: 24rpx;
}

.skeleton-card {
  height: 320rpx;
  border-radius: 24rpx;
  background: linear-gradient(90deg, #f0ece8 25%, #e8e4df 50%, #f0ece8 75%);
  background-size: 400% 100%;
  animation: shimmer 1.4s infinite;
}

/* ── Empty ────────────────────────────────── */
.empty-wrap {
  padding: 80rpx 24rpx;
}

.empty-card {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, #E8D5C4, #D8C8DC);
  border-radius: 24rpx;
  padding: 64rpx 40rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16rpx;
}

.empty-deco {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;

  &--1 {
    width: 200rpx;
    height: 200rpx;
    top: -60rpx;
    right: -40rpx;
    background: rgba(255, 255, 255, 0.3);
  }

  &--2 {
    width: 140rpx;
    height: 140rpx;
    bottom: -40rpx;
    left: -20rpx;
    background: rgba(255, 255, 255, 0.2);
  }
}

.empty-title {
  font-size: 34rpx;
  font-weight: 700;
  color: $brand-color;
  z-index: 1;
}

.empty-sub {
  font-size: 26rpx;
  color: $text-secondary;
  z-index: 1;
}

.empty-btn {
  margin-top: 16rpx;
  padding: 20rpx 56rpx;
  border-radius: 40rpx;
  background: rgba(74, 64, 53, 0.12);
  z-index: 1;

  &:active { background: rgba(74, 64, 53, 0.18); }
}

.empty-btn-text {
  font-size: 28rpx;
  color: $brand-color;
  font-weight: 600;
}

/* ── List ─────────────────────────────────── */
.list {
  padding: 16rpx 24rpx 0;
}

/* ── Group ────────────────────────────────── */
.group-section {
  margin-bottom: 16rpx;
}

.group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12rpx 8rpx 16rpx;
}

.group-title {
  font-size: 28rpx;
  color: $text-primary;
  font-weight: 600;
}

.group-count {
  font-size: 22rpx;
  color: $text-hint;
}

/* ══════════════════════════════════════════════
   MEMBERSHIP CARD (mc)
   ══════════════════════════════════════════════ */
.mc {
  position: relative;
  overflow: hidden;
  border-radius: 24rpx;
  padding: 28rpx 32rpx;
  margin-bottom: 20rpx;
  display: flex;
  flex-direction: column;
  gap: 24rpx;
}

/* Card type backgrounds */
.mc--times {
  background: linear-gradient(135deg, #EDE0D4 0%, #E2D2C2 100%);
  box-shadow: 0 4rpx 20rpx rgba(212, 191, 168, 0.3);
}

.mc--duration {
  background: linear-gradient(135deg, #E0D4E4 0%, #D4C6DA 100%);
  box-shadow: 0 4rpx 20rpx rgba(196, 174, 203, 0.3);
}

.mc--trial {
  background: linear-gradient(135deg, #D4E2DC 0%, #C6D8D0 100%);
  box-shadow: 0 4rpx 20rpx rgba(169, 196, 188, 0.3);
}

.mc--inactive {
  background: linear-gradient(135deg, #E8E4E0, #DDD9D5);
  box-shadow: 0 2rpx 12rpx rgba(180, 160, 130, 0.12);
  opacity: 0.75;
  gap: 16rpx;
}

/* Decorative circles */
.mc-deco {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;

  &--1 {
    width: 180rpx;
    height: 180rpx;
    top: -50rpx;
    right: -30rpx;
    background: rgba(255, 255, 255, 0.3);
  }

  &--2 {
    width: 120rpx;
    height: 120rpx;
    bottom: -30rpx;
    left: 40rpx;
    background: rgba(255, 255, 255, 0.2);
  }
}

/* ── Top row ──────────────────────────────── */
.mc-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  z-index: 1;
}

.mc-name-area {
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.mc-name {
  font-size: 34rpx;
  font-weight: 700;
  color: #2C2420;
  line-height: 1.2;
}

.mc-type-tag {
  align-self: flex-start;
  padding: 4rpx 14rpx;
  border-radius: 10rpx;
  background: rgba(44, 36, 32, 0.1);
}

.mc-type-text {
  font-size: 20rpx;
  color: rgba(44, 36, 32, 0.6);
  font-weight: 500;
}

/* Status */
.mc-status {
  display: flex;
  align-items: center;
  gap: 8rpx;
  padding: 6rpx 16rpx;
  border-radius: 16rpx;
  flex-shrink: 0;
}

.mc-status--active {
  background: rgba(122, 158, 126, 0.18);
}

.mc-status--expired,
.mc-status--used {
  background: rgba(74, 64, 53, 0.08);
}

.mc-status-dot {
  width: 10rpx;
  height: 10rpx;
  border-radius: 50%;
  background: $success-color;
}

.mc-status-text {
  font-size: 22rpx;
  color: #2C2420;
  font-weight: 600;
}

/* ── Center: big number ───────────────────── */
.mc-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8rpx 0;
  z-index: 1;
}

.mc-big-num {
  font-size: 80rpx;
  font-weight: 800;
  color: #2C2420;
  line-height: 1;
  font-family: 'DIN Alternate', 'Helvetica Neue', Arial, sans-serif;
}

.mc-big-unit {
  font-size: 24rpx;
  color: rgba(44, 36, 32, 0.55);
  font-weight: 500;
  margin-top: 4rpx;
}

/* Progress */
.mc-progress {
  width: 100%;
  max-width: 400rpx;
  margin-top: 20rpx;
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.mc-progress-track {
  height: 10rpx;
  background: rgba(44, 36, 32, 0.1);
  border-radius: 5rpx;
  overflow: hidden;
}

.mc-progress-fill {
  height: 100%;
  background: rgba(44, 36, 32, 0.35);
  border-radius: 5rpx;
  transition: width 0.4s ease;
}

.mc-progress-label {
  font-size: 20rpx;
  color: rgba(44, 36, 32, 0.45);
  text-align: center;
}

/* ── Bottom: dates ────────────────────────── */
.mc-bottom {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  z-index: 1;
  padding-top: 4rpx;
  border-top: 1rpx solid rgba(44, 36, 32, 0.1);
}

.mc-date-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4rpx;
}

.mc-date-sep {
  width: 1rpx;
  height: 40rpx;
  background: rgba(44, 36, 32, 0.12);
  flex-shrink: 0;
}

.mc-date-label {
  font-size: 20rpx;
  color: rgba(44, 36, 32, 0.4);
}

.mc-date-value {
  font-size: 24rpx;
  color: #2C2420;
  font-weight: 600;
}

/* ── Inactive info ────────────────────────── */
.mc-inactive-info {
  display: flex;
  gap: 40rpx;
  padding-left: 4rpx;
  z-index: 1;
}

/* ── FAB ──────────────────────────────────── */
.fab {
  position: fixed;
  bottom: calc(32rpx + env(safe-area-inset-bottom));
  right: 32rpx;
  background: $brand-color;
  border-radius: 44rpx;
  padding: 22rpx 36rpx;
  box-shadow: 0 6rpx 24rpx rgba(74, 64, 53, 0.25);
  z-index: 100;

  &:active { opacity: 0.85; }
}

.fab-text {
  font-size: 28rpx;
  font-weight: 600;
  color: #fff;
  letter-spacing: 1rpx;
}

/* ── Spacer ───────────────────────────────── */
.scroll-bottom-spacer {
  height: 140rpx;
}
</style>
