<template>
  <view class="membership-page" :style="{ paddingTop: navBarHeight }">
    <CustomNavBar title="我的会员卡" show-back />
    <!-- Pull-to-refresh scroll view -->
    <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">
        <text class="empty-icon">💳</text>
        <text class="empty-title">暂无会员卡</text>
        <text class="empty-sub">购买会员卡后即可预约课程</text>
        <view class="empty-btn" @tap="goStore">
          <text class="empty-btn-text">去购买</text>
        </view>
      </view>

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

          <view
            v-for="m in activeMemberships"
            :key="m.id"
            class="card-item"
          >
            <!-- Colored left border strip -->
            <view class="card-strip" :class="stripClass(m.cardType.type)" />

            <!-- Card header (colored gradient) -->
            <view class="card-header" :class="headerClass(m.cardType.type)">
              <view class="card-header-left">
                <text class="card-name">{{ m.cardType.name }}</text>
                <view class="card-type-badge">
                  <text class="card-type-badge-text">{{ typeLabel(m.cardType.type) }}</text>
                </view>
              </view>
              <view class="status-badge status-badge--active">
                <text class="status-badge-text">有效</text>
              </view>
            </view>

            <!-- Card body -->
            <view class="card-body">
              <!-- Times card: remaining times + progress -->
              <template v-if="m.remainingTimes !== null">
                <view class="highlight-row">
                  <text class="highlight-label">剩余课时</text>
                  <text class="highlight-value">
                    <text class="highlight-number">{{ m.remainingTimes }}</text>
                    <text class="highlight-unit"> 次</text>
                  </text>
                </view>
                <view v-if="m.cardType.totalTimes" class="progress-wrap">
                  <view class="progress-bar">
                    <view
                      class="progress-fill"
                      :style="{ width: progressWidth(m) }"
                    />
                  </view>
                  <text class="progress-label">
                    已使用 {{ usedTimes(m) }} / {{ m.cardType.totalTimes }} 次
                  </text>
                </view>
              </template>

              <!-- Duration card: expiry -->
              <view class="info-row">
                <text class="info-label">有效期至</text>
                <text class="info-value">{{ m.expireDate.slice(0, 10) }}</text>
              </view>
              <view class="info-row">
                <text class="info-label">开始日期</text>
                <text class="info-value">{{ m.startDate.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">
            <view class="group-dot group-dot--inactive" />
            <text class="group-title">历史记录</text>
            <text class="group-count">{{ inactiveMemberships.length }} 张</text>
          </view>

          <view
            v-for="m in inactiveMemberships"
            :key="m.id"
            class="card-item card-item--inactive"
          >
            <view class="card-strip card-strip--inactive" />
            <view class="card-header card-header--inactive">
              <view class="card-header-left">
                <text class="card-name card-name--dim">{{ m.cardType.name }}</text>
                <view class="card-type-badge card-type-badge--dim">
                  <text class="card-type-badge-text">{{ typeLabel(m.cardType.type) }}</text>
                </view>
              </view>
              <view class="status-badge" :class="statusBadgeClass(m.status)">
                <text class="status-badge-text">{{ statusLabel(m.status) }}</text>
              </view>
            </view>
            <view class="card-body">
              <view v-if="m.remainingTimes !== null" class="info-row">
                <text class="info-label">剩余课时</text>
                <text class="info-value">{{ m.remainingTimes }} 次</text>
              </view>
              <view class="info-row">
                <text class="info-label">有效期至</text>
                <text class="info-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-icon">+</text>
      <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 CustomNavBar from '../../components/CustomNavBar.vue'

const userStore = useUserStore()

// ─── Nav bar height ──────────────────────────────────────
const navBarHeight = ref('64px')
// ─── State ────────────────────────────────────────────────
const loading = ref(false)
const refreshing = ref(false)

// ─── Computed from store ───────────────────────────────────
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),
)

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

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

function statusBadgeClass(status: MembershipStatus): string {
  if (status === MembershipStatus.EXPIRED) return 'status-badge--expired'
  if (status === MembershipStatus.USED_UP) return 'status-badge--used'
  return 'status-badge--expired'
}

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

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

function progressWidth(m: MembershipWithCardType): string {
  if (m.remainingTimes === null || !m.cardType.totalTimes) return '0%'
  const pct = (m.remainingTimes / m.cardType.totalTimes) * 100
  return `${Math.max(0, Math.min(100, pct))}%`
}

function usedTimes(m: MembershipWithCardType): number {
  if (m.remainingTimes === null || !m.cardType.totalTimes) return 0
  return m.cardType.totalTimes - m.remainingTimes
}

// ─── Data loading ─────────────────────────────────────────
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' })
}

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

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

.scroll {
  height: 100vh;
}

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

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

/* ── Empty ───────────────────────────────────────────── */
.empty-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 120rpx 40rpx;
  gap: 20rpx;
}

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

.empty-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #333;
}

.empty-sub {
  font-size: 26rpx;
  color: #999;
}

.empty-btn {
  margin-top: 12rpx;
  padding: 22rpx 60rpx;
  border-radius: 44rpx;
  background: $primary-dark;
  box-shadow: 0 4rpx 16rpx rgba(201, 168, 124, 0.35);
}

.empty-btn-text {
  font-size: 30rpx;
  color: #fff;
  font-weight: 600;
}

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

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

.group-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10rpx;
  padding: 8rpx 4rpx 14rpx;
}

.group-dot {
  width: 12rpx;
  height: 12rpx;
  border-radius: 50%;
  flex-shrink: 0;

  &--active   { background: #4caf50; }
  &--inactive { background: #bbb; }
}

.group-title {
  font-size: 26rpx;
  color: #555;
  font-weight: 600;
  flex: 1;
}

.group-count {
  font-size: 22rpx;
  color: #bbb;
}

/* ── Card item ───────────────────────────────────────── */
.card-item {
  background: #fff;
  border-radius: 20rpx;
  overflow: hidden;
  margin-bottom: 16rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.07);
  display: flex;
  flex-direction: column;

  &--inactive {
    opacity: 0.72;
  }
}

/* Colored left border strip */
.card-strip {
  height: 6rpx;

  &--times    { background: linear-gradient(90deg, #1a1a2e, #2d2d5e); }
  &--duration { background: linear-gradient(90deg, #6c3483, #9b59b6); }
  &--trial    { background: linear-gradient(90deg, #5a7a8a, $primary-dark); }
  &--inactive { background: #ccc; }
}

/* Card header gradient area */
.card-header {
  padding: 22rpx 28rpx;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;

  &--times    { background: linear-gradient(90deg, #1a1a2e, #2d2d5e); }
  &--duration { background: linear-gradient(90deg, #6c3483, #9b59b6); }
  &--trial    { background: linear-gradient(90deg, #5a7a8a, $primary-dark); }
  &--inactive { background: #888; }
}

.card-header-left {
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.card-name {
  font-size: 32rpx;
  font-weight: 700;
  color: #fff;

  &--dim { color: #ddd; }
}

.card-type-badge {
  align-self: flex-start;
  padding: 4rpx 14rpx;
  border-radius: 12rpx;
  background: rgba(255, 255, 255, 0.15);
  border: 1rpx solid rgba(255, 255, 255, 0.25);

  &--dim {
    background: rgba(255, 255, 255, 0.08);
  }
}

.card-type-badge-text {
  font-size: 20rpx;
  color: rgba(255, 255, 255, 0.85);
  font-weight: 500;
}

/* Status badge */
.status-badge {
  padding: 8rpx 20rpx;
  border-radius: 20rpx;
  border: 1rpx solid rgba(255, 255, 255, 0.35);
  flex-shrink: 0;

  &--active  { background: rgba(76, 175, 80, 0.3); }
  &--expired { background: rgba(0, 0, 0, 0.2); }
  &--used    { background: rgba(0, 0, 0, 0.2); }
}

.status-badge-text {
  font-size: 22rpx;
  color: #fff;
  font-weight: 600;
}

/* Card body */
.card-body {
  padding: 20rpx 28rpx 24rpx;
  display: flex;
  flex-direction: column;
  gap: 10rpx;
}

.highlight-row {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 4rpx;
}

.highlight-label {
  font-size: 26rpx;
  color: #999;
}

.highlight-number {
  font-size: 44rpx;
  font-weight: 800;
  color: $primary-dark;
  line-height: 1;
}

.highlight-unit {
  font-size: 22rpx;
  color: $primary-dark;
  font-weight: 500;
}

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

.info-label {
  font-size: 26rpx;
  color: #999;
}

.info-value {
  font-size: 26rpx;
  color: #333;
  font-weight: 500;
}

/* ── Progress bar ────────────────────────────────────── */
.progress-wrap {
  display: flex;
  flex-direction: column;
  gap: 8rpx;
  margin-bottom: 6rpx;
}

.progress-bar {
  height: 8rpx;
  background: #f0f0f0;
  border-radius: 4rpx;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, $primary-dark, $primary-color);
  border-radius: 4rpx;
  transition: width 0.4s ease;
}

.progress-label {
  font-size: 22rpx;
  color: #bbb;
  text-align: right;
}

/* ── FAB ─────────────────────────────────────────────── */
.fab {
  position: fixed;
  bottom: calc(32rpx + env(safe-area-inset-bottom));
  right: 32rpx;
  background: #1a1a2e;
  border-radius: 44rpx;
  padding: 22rpx 36rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.2);
  z-index: 100;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8rpx;

  &:active {
    opacity: 0.85;
  }
}

.fab-icon {
  font-size: 36rpx;
  color: $primary-dark;
  font-weight: 300;
  line-height: 1;
}

.fab-text {
  font-size: 28rpx;
  font-weight: 700;
  color: $primary-dark;
  letter-spacing: 1rpx;
}

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