<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import {
  getMemberStatistics,
  getBookingStatistics,
  getSignInStatistics,
  exportStatistics,
  type MemberStatistics,
  type BookingStatistics,
  type SignInStatistics,
} from '@/api/datacount'
import AppLayout from '@/components/AppLayout.vue'

const router = useRouter()

const memberStats = ref<MemberStatistics | null>(null)
const bookingStats = ref<BookingStatistics | null>(null)
const signInStats = ref<SignInStatistics | null>(null)
const loading = ref(true)
const exporting = ref(false)
const periodType = ref('DAY')
const showDatePicker = ref(false)

const startDate = ref('')
const endDate = ref('')

const periodOptions = [
  { label: '今日', value: 'DAY' },
  { label: '本周', value: 'WEEK' },
  { label: '本月', value: 'MONTH' },
  { label: '本年', value: 'YEAR' },
  { label: '总计', value: 'ALL' },
  { label: '自定义', value: 'CUSTOM' },
]

const periodLabel = computed(() => {
  switch (periodType.value) {
    case 'WEEK': return '本周新增'
    case 'MONTH': return '本月新增'
    case 'YEAR': return '本年新增'
    case 'ALL': return '累计'
    case 'CUSTOM': return '区间新增'
    default: return '今日新增'
  }
})

const statsValues = ref({
  totalMembers: 0,
  newMembers: 0,
  totalBookings: 0,
  totalSignIns: 0,
})

const statsCards = computed(() => [
  { label: '会员总数', value: statsValues.value.totalMembers, color: '#4f7cff', icon: 'fa-users', clickable: false },
  { label: periodLabel.value, value: statsValues.value.newMembers, color: '#10b981', icon: 'fa-user-plus', clickable: false },
  { label: '预约总数', value: statsValues.value.totalBookings, color: '#f59e0b', icon: 'fa-calendar-check', clickable: false },
  { label: '签到总数', value: statsValues.value.totalSignIns, color: '#ec4899', icon: 'fa-clipboard-check', clickable: true, route: '/member-signin' },
])

function handleCardClick(card: { clickable?: boolean; route?: string }) {
  if (card.clickable && card.route) {
    router.push(card.route)
  }
}

const recentActivities = ref([
  { title: '会员签到', time: '--', dot: '' },
  { title: '团课预约', time: '--', dot: 'green' },
  { title: '新会员注册', time: '--', dot: 'orange' },
  { title: '课程取消', time: '--', dot: 'pink' },
])

function formatDateTime(dateStr: string, isEnd: boolean): string {
  if (!dateStr) return ''
  return isEnd ? dateStr + 'T23:59:59' : dateStr + 'T00:00:00'
}

async function fetchData() {
  loading.value = true
  try {
    const params: Record<string, string> = {}
    if (periodType.value === 'CUSTOM') {
      if (startDate.value) params.startTime = formatDateTime(startDate.value, false)
      if (endDate.value) params.endTime = formatDateTime(endDate.value, true)
    } else {
      params.periodType = periodType.value
    }

    const [mem, book, sign] = await Promise.all([
      getMemberStatistics(params),
      getBookingStatistics(params),
      getSignInStatistics(params),
    ])
    memberStats.value = mem
    bookingStats.value = book
    signInStats.value = sign

    statsValues.value.totalMembers = Number(mem.totalMembers) || 0
    statsValues.value.newMembers = Number(mem.newMembers) || 0
    statsValues.value.totalBookings = Number(book.newBookings) || 0
    statsValues.value.totalSignIns = Number(sign.totalSignIns) || 0

    const now = new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
    recentActivities.value = [
      { title: '签到成功 ' + (Number(sign.successSignIns) || 0) + ' 次', time: now, dot: '' },
      { title: '预约 ' + (Number(book.newBookings) || 0) + ' 单', time: now, dot: 'green' },
      { title: '新增会员 ' + (Number(mem.newMembers) || 0) + ' 人', time: now, dot: 'orange' },
      { title: '取消预约 ' + (Number(book.cancelBookings) || 0) + ' 单', time: now, dot: 'pink' },
    ]
  } catch {
    memberStats.value = null
    bookingStats.value = null
    signInStats.value = null
  } finally {
    loading.value = false
  }
}

function changePeriod(value: string) {
  periodType.value = value
  showDatePicker.value = value === 'CUSTOM'
  if (value !== 'CUSTOM') {
    fetchData()
  }
}

function handleCustomQuery() {
  if (!startDate.value && !endDate.value) return
  fetchData()
}

async function handleExport() {
  exporting.value = true
  try {
    const params: Record<string, string> = {}
    if (periodType.value === 'CUSTOM') {
      if (startDate.value) params.startTime = formatDateTime(startDate.value, false)
      if (endDate.value) params.endTime = formatDateTime(endDate.value, true)
    } else {
      params.periodType = periodType.value
    }
    const blob = await exportStatistics(params)
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    const now = new Date()
    const filename = `数据报表_${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}${String(now.getSeconds()).padStart(2, '0')}.xlsx`
    link.download = filename
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
  } catch {
    // 导出失败
  } finally {
    exporting.value = false
  }
}

function today(): string {
  return new Date().toISOString().slice(0, 10)
}

onMounted(fetchData)
</script>

<template>
  <AppLayout>
    <div class="period-bar">
      <div class="period-selector">
        <button
          v-for="opt in periodOptions"
          :key="opt.value"
          class="period-btn"
          :class="{ active: periodType === opt.value }"
          @click="changePeriod(opt.value)"
        >
          {{ opt.label }}
        </button>
      </div>

      <transition name="fade">
        <div v-if="showDatePicker" class="date-range">
          <label>开始日期</label>
          <input v-model="startDate" type="date" :max="endDate || today()" />
          <label>结束日期</label>
          <input v-model="endDate" type="date" :min="startDate" :max="today()" />
          <button class="btn btn-primary" @click="handleCustomQuery">
            <i class="fas fa-search"></i> 查询
          </button>
        </div>
      </transition>

      <button class="btn btn-export" :disabled="exporting || loading" @click="handleExport">
        <i class="fas fa-download"></i>
        <span>{{ exporting ? '导出中...' : '导出报表' }}</span>
      </button>
    </div>

    <section class="stats-grid">
      <template v-if="loading">
        <div class="stat-card skeleton-card" v-for="i in 4" :key="'sk-' + i">
          <div class="sk-label skeleton"></div>
          <div class="sk-value skeleton"></div>
        </div>
      </template>
      <template v-else>
        <div
          class="stat-card"
          :class="{ 'stat-card-clickable': card.clickable }"
          v-for="card in statsCards"
          :key="card.label"
          @click="handleCardClick(card)"
        >
          <div class="stat-card-inner">
            <div class="stat-icon" :style="{ background: card.color + '18', color: card.color }">
              <i :class="'fas ' + card.icon"></i>
            </div>
            <div class="stat-body">
              <div class="label">{{ card.label }}</div>
              <div class="value" :style="{ color: card.color }">
                {{ card.value.toLocaleString() }}
              </div>
            </div>
          </div>
        </div>
      </template>
    </section>

    <section class="content-grid">
      <div class="card">
        <div class="card-header">
          <h3><i class="fas fa-chart-bar" style="margin-right: 8px; color: #4f7cff"></i>数据概览</h3>
        </div>
        <template v-if="loading">
          <div class="detail-grid">
            <div class="detail-item" v-for="i in 4" :key="'ds-' + i">
              <div class="sk-label-small skeleton" style="width:60%;margin:0 auto 8px"></div>
              <div class="sk-value-small skeleton" style="width:40%;margin:0 auto"></div>
            </div>
          </div>
        </template>
        <template v-else-if="memberStats">
          <div class="detail-grid">
            <div class="detail-item">
              <span class="detail-label">出席率</span>
              <span class="detail-value">{{ bookingStats?.attendanceRate ?? '--' }}%</span>
            </div>
            <div class="detail-item">
              <span class="detail-label">取消率</span>
              <span class="detail-value down">{{ bookingStats?.cancelRate ?? '--' }}%</span>
            </div>
            <div class="detail-item">
              <span class="detail-label">签到成功率</span>
              <span class="detail-value">{{ signInStats?.successRate ?? '--' }}%</span>
            </div>
            <div class="detail-item">
              <span class="detail-label">活跃会员</span>
              <span class="detail-value">{{ memberStats?.activeMembers ?? 0 }}</span>
            </div>
          </div>
        </template>
        <div v-else class="empty-state">暂无数据</div>
      </div>

      <div class="card">
        <div class="card-header">
          <h3><i class="fas fa-clock" style="margin-right: 8px; color: #4f7cff"></i>最近动态</h3>
        </div>
        <template v-if="loading">
          <div class="activity-list">
            <div class="activity-item" v-for="i in 4" :key="'as-' + i">
              <div class="sk-dot skeleton"></div>
              <div class="activity-content">
                <div class="sk-line skeleton" style="width:70%"></div>
                <div class="sk-line skeleton" style="width:40%;margin-top:6px"></div>
              </div>
            </div>
          </div>
        </template>
        <template v-else>
          <div class="activity-list">
            <div class="activity-item" v-for="(item, idx) in recentActivities" :key="idx">
              <div class="activity-dot" :class="item.dot"></div>
              <div class="activity-content">
                <div class="title">{{ item.title }}</div>
                <div class="time">{{ item.time }}</div>
              </div>
            </div>
          </div>
        </template>
      </div>
    </section>
  </AppLayout>
</template>

<style scoped>
/* ---- period ---- */
.period-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}

.period-selector {
  display: flex;
  gap: 8px;
}

.period-btn {
  padding: 8px 20px;
  border-radius: 20px;
  border: 1px solid #e2e8f0;
  background: white;
  font-size: 13px;
  font-weight: 500;
  color: #3e4e62;
  cursor: pointer;
  transition: 0.15s;
  white-space: nowrap;
}

.period-btn.active {
  background: #4f7cff;
  border-color: #4f7cff;
  color: white;
}

.period-btn:hover:not(.active) {
  background: #f0f5ff;
}

/* ---- date range ---- */
.date-range {
  display: flex;
  align-items: center;
  gap: 8px;
  background: white;
  padding: 8px 14px;
  border-radius: 16px;
  border: 1px solid #edf2f9;
  animation: fadeIn 0.25s ease;
}

.date-range label {
  font-size: 13px;
  color: #6b7d94;
  font-weight: 500;
}

.date-range input {
  padding: 6px 10px;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  font-size: 13px;
  color: #1e293b;
  outline: none;
}

.btn {
  padding: 7px 16px;
  border-radius: 20px;
  border: 1px solid #e2e8f0;
  background: white;
  font-weight: 500;
  font-size: 13px;
  color: #1e293b;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  transition: 0.15s;
}

.btn-primary {
  background: #4f7cff;
  border-color: #4f7cff;
  color: white;
}

.btn-primary:hover { background: #3b6bf0; }

.btn-export {
  background: #10b981;
  border-color: #10b981;
  color: white;
  padding: 8px 18px;
  border-radius: 20px;
  font-weight: 500;
  font-size: 13px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  transition: 0.15s;
  margin-left: auto;
}

.btn-export:hover { background: #059669; }
.btn-export:disabled { opacity: 0.6; cursor: not-allowed; }

/* ---- stats grid ---- */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.stat-card {
  background: white;
  border-radius: 20px;
  border: 1px solid #edf2f9;
  padding: 24px 20px;
  animation: fadeIn 0.4s ease;
}

.stat-card-clickable {
  cursor: pointer;
  transition: box-shadow 0.2s, transform 0.2s;
}

.stat-card-clickable:hover {
  box-shadow: 0 4px 16px rgba(236, 72, 153, 0.15);
  transform: translateY(-2px);
}

.stat-card-inner {
  display: flex;
  align-items: center;
  gap: 16px;
}

.stat-icon {
  width: 48px;
  height: 48px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex-shrink: 0;
}

.stat-body .label {
  font-size: 13px;
  color: #6b7d94;
  margin-bottom: 4px;
}

.stat-body .value {
  font-size: 28px;
  font-weight: 700;
}

/* ---- content grid ---- */
.content-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.card {
  background: white;
  border-radius: 20px;
  border: 1px solid #edf2f9;
  padding: 20px 24px;
}

.card-header {
  margin-bottom: 16px;
}

.card-header h3 {
  font-weight: 600;
  font-size: 16px;
  color: #0b1a33;
}

/* ---- detail grid ---- */
.detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.detail-item {
  text-align: center;
  padding: 12px;
  background: #f8fafd;
  border-radius: 14px;
}

.detail-label {
  display: block;
  font-size: 12px;
  color: #8b9ab0;
  margin-bottom: 4px;
}

.detail-value {
  font-size: 20px;
  font-weight: 700;
  color: #1e293b;
}

.detail-value.down { color: #ef4444; }

/* ---- activity ---- */
.activity-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.activity-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid #f1f5fa;
}

.activity-item:last-child { border-bottom: none; }

.activity-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #4f7cff;
  flex-shrink: 0;
}

.activity-dot.green { background: #10b981; }
.activity-dot.orange { background: #f59e0b; }
.activity-dot.pink { background: #ec4899; }

.activity-content .title {
  font-size: 14px;
  color: #1e293b;
  font-weight: 500;
}

.activity-content .time {
  font-size: 12px;
  color: #8b9ab0;
  margin-top: 2px;
}

.empty-state {
  text-align: center;
  padding: 32px;
  color: #8b9ab0;
  font-size: 14px;
}

/* ---- skeleton ---- */
.skeleton {
  background: linear-gradient(90deg, #eef2f8 25%, #e0e7f0 50%, #eef2f8 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: 8px;
}

.skeleton-card { padding: 28px 20px; }

.sk-label {
  height: 14px;
  width: 50%;
  margin-bottom: 12px;
  border-radius: 6px;
}

.sk-value {
  height: 30px;
  width: 35%;
  border-radius: 6px;
}

.sk-label-small { height: 12px; display: block; }
.sk-value-small { height: 22px; display: block; }

.sk-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

.sk-line {
  height: 14px;
  border-radius: 6px;
}

/* ---- animations ---- */
@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.fade-enter-active { animation: fadeIn 0.25s ease; }
.fade-leave-active { animation: fadeIn 0.15s ease reverse; }

@media (max-width: 768px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .content-grid { grid-template-columns: 1fr; }
}
</style>
