<template>
  <view class="booking-detail-page" :style="{ paddingTop: navBarHeight }">
    <CustomNavBar title="预约详情" show-back />

    <!-- Loading state -->
    <view v-if="loading" class="loading-wrap">
      <view class="skeleton-card" />
    </view>

    <!-- Error state -->
    <view v-else-if="!booking" class="empty-wrap">
      <text class="empty-title">预约不存在</text>
    </view>

    <template v-else>
      <!-- Booking info card -->
      <view class="info-card">
        <!-- Status banner -->
        <view class="status-banner" :class="bookingStatusBannerClass(booking.status)">
          <text class="status-banner-text">{{ bookingStatusLabel(booking.status) }}</text>
        </view>

        <!-- Course info -->
        <view class="info-section">
          <view class="info-row">
            <text class="info-label">课程日期</text>
            <text class="info-value">{{ formatDateDisplay(booking.timeSlot.date) }}</text>
          </view>
          <view class="info-row">
            <text class="info-label">课程时间</text>
            <text class="info-value">
              {{ booking.timeSlot.startTime.slice(0, 5) }} - {{ booking.timeSlot.endTime.slice(0, 5) }}
            </text>
          </view>
          <view class="info-row">
            <text class="info-label">使用卡种</text>
            <text class="info-value">{{ booking.membership?.cardType?.name }}</text>
          </view>
        </view>

        <!-- User info (for admin view) -->
        <view v-if="isAdmin && bookingUser" class="info-section">
          <view class="section-title">学员信息</view>
          <view class="info-row">
            <text class="info-label">学员姓名</text>
            <text class="info-value">{{ bookingUser.nickname || '匿名用户' }}</text>
          </view>
          <view v-if="bookingUser.phone" class="info-row">
            <text class="info-label">联系电话</text>
            <text class="info-value">{{ bookingUser.phone }}</text>
          </view>
        </view>

        <!-- Timestamps -->
        <view class="info-section">
          <view class="section-title">时间记录</view>
          <view class="info-row">
            <text class="info-label">预约时间</text>
            <text class="info-value">{{ formatDateTime(booking.createdAt) }}</text>
          </view>
          <view v-if="booking.confirmedAt" class="info-row">
            <text class="info-label">确认时间</text>
            <text class="info-value">{{ formatDateTime(booking.confirmedAt) }}</text>
          </view>
          <view v-if="booking.completedAt" class="info-row">
            <text class="info-label">核销时间</text>
            <text class="info-value">{{ formatDateTime(booking.completedAt) }}</text>
          </view>
          <view v-if="booking.cancelledAt" class="info-row">
            <text class="info-label">取消时间</text>
            <text class="info-value">{{ formatDateTime(booking.cancelledAt) }}</text>
          </view>
        </view>
      </view>

      <!-- Status timeline -->
      <view class="timeline-card">
        <view class="timeline-header">
          <text class="timeline-title">状态流转记录</text>
        </view>

        <view v-if="history.length === 0" class="timeline-empty">
          <text class="timeline-empty-text">暂无流转记录</text>
        </view>

        <view v-else class="timeline">
          <view
            v-for="(item, idx) in history"
            :key="item.id"
            class="timeline-item"
            :class="{ 'timeline-item--last': idx === history.length - 1 }"
          >
            <!-- Dot -->
            <view class="timeline-dot-wrap">
              <view class="timeline-dot" :class="bookingTimelineDotClass(item.toStatus)" />
              <view v-if="idx < history.length - 1" class="timeline-line" />
            </view>

            <!-- Content -->
            <view class="timeline-content">
              <view class="timeline-content-header">
                <text class="timeline-status">{{ formatHistoryStatus(item.toStatus) }}</text>
                <text class="timeline-time">{{ formatDateTime(item.createdAt) }}</text>
              </view>
              <text v-if="item.remark" class="timeline-remark">{{ item.remark }}</text>
            </view>
          </view>
        </view>
      </view>

      <!-- Action buttons -->
      <view v-if="showActions" class="action-bar">
        <!-- Pending: confirm button for admin -->
        <view
          v-if="booking.status === 'PENDING_CONFIRMATION' && isAdmin"
          class="action-btn action-btn--confirm"
          @tap="handleConfirm"
        >
          <text class="action-btn-text">确认预约</text>
        </view>

        <!-- Confirmed: complete / noshow buttons for admin -->
        <view v-if="booking.status === 'CONFIRMED' && isAdmin" class="action-row">
          <view class="action-btn action-btn--complete" @tap="handleComplete">
            <text class="action-btn-text">核销完成</text>
          </view>
          <view class="action-btn action-btn--noshow" @tap="handleNoShow">
            <text class="action-btn-text">标记未到</text>
          </view>
        </view>

        <!-- User can cancel if pending or confirmed -->
        <view
          v-if="booking.status === 'PENDING_CONFIRMATION' || booking.status === 'CONFIRMED'"
          class="action-btn action-btn--cancel"
          @tap="handleCancel"
        >
          <text class="action-btn-text">取消预约</text>
        </view>
      </view>
    </template>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import type { BookingWithDetails, BookingWithUser, BookingStatusHistory } from '@mp-pilates/shared'
import { BookingStatus } from '@mp-pilates/shared'
import { useBookingStore } from '../../stores/booking'
import { useUserStore } from '../../stores/user'
import { getSystemLayout } from '../../utils/system'
import {
  formatDateDisplay,
  bookingStatusLabel,
  bookingStatusBannerClass,
  bookingTimelineDotClass,
} from '../../utils/booking-helpers'
import CustomNavBar from '../../components/CustomNavBar.vue'

const bookingStore = useBookingStore()
const userStore = useUserStore()

const navBarHeight = ref('64px')
const loading = ref(false)
const bookingId = ref('')
const booking = ref<BookingWithDetails | BookingWithUser | null>(null)
const history = ref<BookingStatusHistory[]>([])

const isAdmin = computed(() => userStore.isAdmin)
const showActions = computed(() =>
  booking.value?.status === BookingStatus.PENDING_CONFIRMATION ||
  booking.value?.status === BookingStatus.CONFIRMED,
)

// Type guard to check if booking has user property
function hasUser(b: BookingWithDetails | BookingWithUser | null): b is BookingWithUser {
  return b !== null && 'user' in b
}

const bookingUser = computed(() => hasUser(booking.value) ? booking.value.user : null)

// ─── Status helpers ───────────────────────────────────────────────────────
function formatHistoryStatus(status: string): string {
  return bookingStatusLabel(status)
}

function formatDateTime(dateStr: string): string {
  if (!dateStr) return '-'
  const d = new Date(dateStr)
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  const hh = String(d.getHours()).padStart(2, '0')
  const mm = String(d.getMinutes()).padStart(2, '0')
  return `${y}-${m}-${day} ${hh}:${mm}`
}

// ─── Data loading ─────────────────────────────────────────────────────────
async function loadData() {
  loading.value = true
  try {
    // Fetch booking details and history in parallel
    const [bookingData, historyData] = await Promise.all([
      bookingStore.fetchBookingById(bookingId.value),
      bookingStore.fetchBookingHistory(bookingId.value),
    ])

    booking.value = bookingData
    history.value = historyData
  } catch (err) {
    console.error('Load booking detail failed:', err)
    uni.showToast({ title: '加载失败', icon: 'none' })
  } finally {
    loading.value = false
  }
}

// ─── Actions ──────────────────────────────────────────────────────────────
async function handleConfirm() {
  uni.showModal({
    title: '确认预约',
    content: '确认该预约？确认后将扣除会员次数。',
    confirmText: '确认',
    success: async (res) => {
      if (!res.confirm) return
      uni.showLoading({ title: '处理中...' })
      try {
        await bookingStore.confirmBooking(bookingId.value)
        uni.hideLoading()
        uni.showToast({ title: '已确认', icon: 'success' })
        await loadData()
      } catch (err: unknown) {
        uni.hideLoading()
        const msg = err instanceof Error ? err.message : '操作失败'
        uni.showToast({ title: msg, icon: 'none' })
      }
    },
  })
}

async function handleComplete() {
  uni.showModal({
    title: '核销完成',
    content: '标记该课程为已完成？',
    confirmText: '确认',
    success: async (res) => {
      if (!res.confirm) return
      uni.showLoading({ title: '处理中...' })
      try {
        await bookingStore.completeBooking(bookingId.value)
        uni.hideLoading()
        uni.showToast({ title: '已核销', icon: 'success' })
        await loadData()
      } catch (err: unknown) {
        uni.hideLoading()
        const msg = err instanceof Error ? err.message : '操作失败'
        uni.showToast({ title: msg, icon: 'none' })
      }
    },
  })
}

async function handleNoShow() {
  uni.showModal({
    title: '标记未到',
    content: '标记该学员未出席？',
    confirmText: '确认',
    success: async (res) => {
      if (!res.confirm) return
      uni.showLoading({ title: '处理中...' })
      try {
        await bookingStore.markNoShow(bookingId.value)
        uni.hideLoading()
        uni.showToast({ title: '已标记', icon: 'success' })
        await loadData()
      } catch (err: unknown) {
        uni.hideLoading()
        const msg = err instanceof Error ? err.message : '操作失败'
        uni.showToast({ title: msg, icon: 'none' })
      }
    },
  })
}

async function handleCancel() {
  uni.showModal({
    title: '取消预约',
    content: '确定要取消该预约？',
    confirmText: '确认取消',
    confirmColor: '#ef4444',
    success: async (res) => {
      if (!res.confirm) return
      uni.showLoading({ title: '处理中...' })
      try {
        await bookingStore.cancelBooking(bookingId.value)
        uni.hideLoading()
        uni.showToast({ title: '已取消', icon: 'success' })
        await loadData()
      } catch (err: unknown) {
        uni.hideLoading()
        const msg = err instanceof Error ? err.message : '操作失败'
        uni.showToast({ title: msg, icon: 'none' })
      }
    },
  })
}

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

onLoad((query) => {
  bookingId.value = (query as Record<string, string>).id || ''
  if (bookingId.value) {
    loadData()
  }
})
</script>

<style lang="scss" scoped>
.booking-detail-page {
  min-height: 100vh;
  background: $primary-bg;
  padding-bottom: 40rpx;
}

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

.skeleton-card {
  height: 300rpx;
  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;
  padding: 120rpx 40rpx;
}

.empty-title {
  font-size: 32rpx;
  color: #666;
}

/* ── Info card ────────────────────────────────────────── */
.info-card {
  margin: 24rpx;
  background: #fff;
  border-radius: 20rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.05);
}

.status-banner {
  padding: 24rpx;
  display: flex;
  align-items: center;
  justify-content: center;

  &--pending { background: rgba(245, 158, 11, 0.1); }
  &--confirmed { background: rgba(201, 168, 124, 0.1); }
  &--completed { background: rgba(102, 187, 106, 0.1); }
  &--cancelled { background: rgba(0, 0, 0, 0.04); }
  &--noshow { background: rgba(239, 83, 80, 0.1); }
}

.status-banner-text {
  font-size: 32rpx;
  font-weight: 600;

  .status-banner--pending & { color: #f59e0b; }
  .status-banner--confirmed & { color: $primary-dark; }
  .status-banner--completed & { color: #66bb6a; }
  .status-banner--cancelled & { color: #bbb; }
  .status-banner--noshow & { color: #ef5350; }
}

.info-section {
  padding: 24rpx;
  border-bottom: 1rpx solid #f5f5f5;

  &:last-child {
    border-bottom: none;
  }
}

.section-title {
  font-size: 24rpx;
  font-weight: 600;
  color: #A09080;
  margin-bottom: 16rpx;
  letter-spacing: 1rpx;
}

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

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

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

/* ── Timeline card ────────────────────────────────────── */
.timeline-card {
  margin: 24rpx;
  background: #fff;
  border-radius: 20rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.05);
}

.timeline-header {
  padding: 24rpx;
  border-bottom: 1rpx solid #f5f5f5;
}

.timeline-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #333;
}

.timeline-empty {
  padding: 48rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.timeline-empty-text {
  font-size: 26rpx;
  color: #bbb;
}

.timeline {
  padding: 24rpx;
  display: flex;
  flex-direction: column;
}

.timeline-item {
  display: flex;
  flex-direction: row;
  gap: 16rpx;
}

.timeline-dot-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

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

  &.dot--pending { background: #f59e0b; }
  &.dot--confirmed { background: $primary-dark; }
  &.dot--completed { background: #66bb6a; }
  &.dot--cancelled { background: #e0e0e0; }
  &.dot--noshow { background: #ef5350; }
}

.timeline-line {
  width: 2rpx;
  flex: 1;
  min-height: 40rpx;
  background: #e8e8e8;
  margin: 4rpx 0;
}

.timeline-item--last .timeline-line {
  display: none;
}

.timeline-content {
  flex: 1;
  padding-bottom: 28rpx;
}

.timeline-content-header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6rpx;
}

.timeline-status {
  font-size: 28rpx;
  font-weight: 600;
  color: #333;
}

.timeline-time {
  font-size: 22rpx;
  color: #bbb;
}

.timeline-remark {
  font-size: 24rpx;
  color: #888;
  display: block;
  margin-top: 4rpx;
}

/* ── Action bar ──────────────────────────────────────── */
.action-bar {
  margin: 24rpx;
  display: flex;
  flex-direction: column;
  gap: 16rpx;
}

.action-row {
  display: flex;
  flex-direction: row;
  gap: 16rpx;
}

.action-btn {
  flex: 1;
  padding: 28rpx 0;
  border-radius: 44rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.15s;

  &:active {
    opacity: 0.85;
  }

  &--confirm {
    background: linear-gradient(135deg, $primary-color, $primary-dark);
  }

  &--complete {
    background: linear-gradient(135deg, #66bb6a, #4caf50);
  }

  &--noshow {
    background: rgba(239, 83, 80, 0.1);
  }

  &--cancel {
    background: rgba(0, 0, 0, 0.04);
  }
}

.action-btn-text {
  font-size: 32rpx;
  font-weight: 600;
  color: #fff;

  .action-btn--cancel & {
    color: #666;
  }

  .action-btn--noshow & {
    color: #ef5350;
  }
}
</style>
