<template>
  <view class="user-card">
    <!-- Header: gradient background -->
    <view class="user-card__header">
      <!-- Not logged in state -->
      <view v-if="!loggedIn" class="user-card__guest">
        <view class="user-card__avatar-wrap">
          <image class="user-card__avatar-img" src="/static/default-avatar.png" mode="aspectFill" />
        </view>
        <view class="user-card__guest-info">
          <text class="user-card__guest-title">Hi，欢迎来到普拉提</text>
          <text class="user-card__guest-sub">登录后查看个人数据</text>
        </view>
        <button class="user-card__login-btn" :loading="loading" @tap="handleLogin">
          微信登录
        </button>
      </view>

      <!-- Logged in + profile loaded -->
      <view v-else-if="loggedIn && hasProfile" class="user-card__user">
        <view class="user-card__avatar-wrap">
          <image
            class="user-card__avatar-img"
            :src="avatarSrc"
            mode="aspectFill"
            @error="onAvatarError"
          />
          <view class="user-card__vip-badge" v-if="vipLevel">
            <text class="user-card__vip-text">{{ vipLevel }}</text>
          </view>
        </view>
        <view class="user-card__info">
          <view class="user-card__name-row">
            <text class="user-card__nickname">{{ user!.nickname }}</text>
          </view>
          <text v-if="maskedPhone" class="user-card__phone">{{ maskedPhone }}</text>
        </view>
      </view>

      <!-- Logged in but profile still loading -->
      <view v-else class="user-card__loading">
        <view class="user-card__avatar-wrap">
          <view class="user-card__avatar-skeleton" />
        </view>
        <view class="user-card__info">
          <view class="user-card__name-row">
            <view class="user-card__nickname-skeleton" />
          </view>
          <view class="user-card__phone-skeleton" />
        </view>
      </view>
    </view>

    <!-- Stats row: shown only when profile is loaded -->
    <view v-if="loggedIn && hasProfile" class="user-card__stats">
      <view class="user-card__stat-item">
        <text class="user-card__stat-value">{{ stats?.totalBookings ?? 0 }}</text>
        <text class="user-card__stat-label">总训练(次)</text>
      </view>
      <view class="user-card__stat-divider" />
      <view class="user-card__stat-item">
        <text class="user-card__stat-value">{{ stats?.monthBookings ?? 0 }}</text>
        <text class="user-card__stat-label">本月(次)</text>
      </view>
      <view class="user-card__stat-divider" />
      <view class="user-card__stat-item">
        <text class="user-card__stat-value">{{ remainingSessions }}</text>
        <text class="user-card__stat-label">剩余课时(节)</text>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import type { UserProfileResponse, UserStatsResponse, MembershipWithCardType } from '@mp-pilates/shared'
import { MembershipStatus } from '@mp-pilates/shared'

const props = defineProps<{
  loggedIn: boolean
  hasProfile: boolean
  user: UserProfileResponse | null
  stats: UserStatsResponse | null
  memberships?: readonly MembershipWithCardType[]
  loading?: boolean
}>()

const emit = defineEmits<{
  (e: 'login'): void
}>()

const avatarFailed = ref(false)

// 头像 URL 变化时重置加载错误状态，避免新头像因偶发加载失败而被永久隐藏
watch(
  () => props.user?.avatarUrl,
  (newUrl, oldUrl) => {
    if (newUrl && newUrl !== oldUrl) {
      avatarFailed.value = false
    }
  },
)

const avatarSrc = computed(() => {
  if (avatarFailed.value || !props.user?.avatarUrl) {
    return '/static/default-avatar.png'
  }
  return props.user.avatarUrl
})

const maskedPhone = computed(() => {
  const phone = props.user?.phone
  if (!phone) return null
  return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
})

// Derive VIP level from active memberships count
const activeMemberships = computed(() =>
  props.memberships?.filter((m) => m.status === MembershipStatus.ACTIVE) ?? [],
)

const vipLevel = computed(() => {
  const count = activeMemberships.value.length
  if (count >= 3) return 'VIP3'
  if (count >= 2) return 'VIP2'
  if (count >= 1) return 'VIP1'
  return null
})

// Sum remaining sessions from all active time-based memberships
const remainingSessions = computed(() =>
  activeMemberships.value
    .filter((m) => m.cardType.type === 'TIMES')
    .reduce((sum, m) => sum + m.remainingCount, 0),
)

function onAvatarError() {
  avatarFailed.value = true
}

function handleLogin() {
  emit('login')
}
</script>

<style lang="scss" scoped>
.user-card {
  background: linear-gradient(135deg, #7c3aed 0%, #a855f7 50%, #ec4899 100%);
  border-radius: 0 0 40rpx 40rpx;
  overflow: hidden;

  &__header {
    padding: 60rpx $spacing-lg $spacing-lg;
  }

  // ── Guest state ──
  &__guest {
    display: flex;
    align-items: center;
    gap: $spacing-md;
  }

  &__guest-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: $spacing-xs;
  }

  &__guest-title {
    font-size: 32rpx;
    font-weight: 600;
    color: #ffffff;
  }

  &__guest-sub {
    font-size: 24rpx;
    color: rgba(255, 255, 255, 0.65);
  }

  &__login-btn {
    flex-shrink: 0;
    background: rgba(255, 255, 255, 0.2);
    color: #ffffff;
    font-size: 26rpx;
    font-weight: 500;
    border: none;
    border-radius: $radius-lg;
    padding: 0 $spacing-md;
    height: 64rpx;
    line-height: 64rpx;
    min-width: 160rpx;

    &::after {
      border: none;
    }
  }

  // ── Logged-in user ──
  &__user {
    display: flex;
    align-items: center;
    gap: $spacing-md;
  }

  &__avatar-wrap {
    position: relative;
    flex-shrink: 0;
    width: 120rpx;
    height: 120rpx;
  }

  &__avatar-img {
    width: 120rpx;
    height: 120rpx;
    border-radius: 50%;
    border: 4rpx solid rgba(255, 255, 255, 0.4);
  }

  &__vip-badge {
    position: absolute;
    bottom: -6rpx;
    left: 50%;
    transform: translateX(-50%);
    background: linear-gradient(135deg, #fbbf24, #f59e0b);
    border-radius: 20rpx;
    padding: 2rpx 12rpx;
    border: 2rpx solid #ffffff;
  }

  &__vip-text {
    font-size: 18rpx;
    font-weight: 700;
    color: #7c2d12;
    line-height: 1;
  }

  &__info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8rpx;
  }

  &__name-row {
    display: flex;
    align-items: center;
    gap: $spacing-sm;
  }

  &__nickname {
    font-size: 36rpx;
    font-weight: 600;
    color: #ffffff;
  }

  &__phone {
    font-size: 26rpx;
    color: rgba(255, 255, 255, 0.75);
  }

  // ── Loading state ──
  &__loading {
    display: flex;
    align-items: center;
    gap: $spacing-md;
  }

  &__avatar-skeleton {
    width: 120rpx;
    height: 120rpx;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.3);
  }

  &__nickname-skeleton {
    width: 160rpx;
    height: 36rpx;
    border-radius: $radius-sm;
    background: rgba(255, 255, 255, 0.3);
  }

  &__phone-skeleton {
    width: 120rpx;
    height: 26rpx;
    border-radius: $radius-sm;
    background: rgba(255, 255, 255, 0.2);
    margin-top: 8rpx;
  }

  // ── Stats row ──
  &__stats {
    display: flex;
    align-items: stretch;
    background: rgba(255, 255, 255, 0.15);
    margin: 0 $spacing-lg $spacing-lg;
    border-radius: $radius-lg;
    padding: $spacing-md 0;
    backdrop-filter: blur(10rpx);
  }

  &__stat-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: $spacing-xs 0;
  }

  &__stat-divider {
    width: 1rpx;
    background: rgba(255, 255, 255, 0.3);
    margin: $spacing-xs 0;
  }

  &__stat-value {
    font-size: 44rpx;
    font-weight: 700;
    color: #ffffff;
    line-height: 1;
  }

  &__stat-label {
    font-size: 22rpx;
    color: rgba(255, 255, 255, 0.8);
    margin-top: 6rpx;
  }
}
</style>
