<template>
  <div class="card-view">
    <div class="card-view__toolbar">
      <a-radio-group :value="groupBy" @change="onGroupChange">
        <a-radio-button value="date">按日期</a-radio-button>
        <a-radio-button value="type">按类型</a-radio-button>
      </a-radio-group>
    </div>

    <a-empty v-if="sortedEvents.length === 0" description="暂无日程" class="card-view__empty" />

    <div v-else class="card-view__groups">
      <div v-for="group in groups" :key="group.key" class="card-view__group">
        <div class="card-view__group-header">
          <span class="card-view__group-label">{{ group.label }}</span>
          <a-tag size="small">{{ group.events.length }}</a-tag>
        </div>
        <div class="card-view__cards">
          <div
            v-for="ev in group.events"
            :key="ev.id"
            class="card-view__card"
            :class="{ 'card-view__card--invited': ev.is_invited }"
            :style="cardStyle(ev)"
            @click="emit('edit', ev)"
          >
            <div class="card-view__card-header">
              <span class="card-view__card-time">{{ formatTime(ev.start_time) }}</span>
              <EventBadge :event="ev" />
              <a-tag v-if="ev.is_invited" color="purple" size="small">受邀</a-tag>
            </div>
            <div class="card-view__card-title">{{ ev.title }}</div>
            <div v-if="ev.location" class="card-view__card-location">
              <EnvironmentOutlined />
              <span>{{ ev.location }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { EnvironmentOutlined } from '@ant-design/icons-vue'
import { useCalendarStore } from '@/stores/calendar'
import type { ICalendarEvent } from '@/api/calendar'
import EventBadge from './EventBadge.vue'

const store = useCalendarStore()

const emit = defineEmits<{
  (e: 'edit', event: ICalendarEvent): void
}>()

const groupBy = ref<'date' | 'type'>('date')

function onGroupChange(e: { target: { value: string } }): void {
  groupBy.value = e.target.value as 'date' | 'type'
}

const sortedEvents = computed(() =>
  [...store.events].sort((a, b) => a.start_time.localeCompare(b.start_time)),
)

interface CardGroup {
  key: string
  label: string
  events: ICalendarEvent[]
}

const groups = computed<CardGroup[]>(() => {
  const map = new Map<string, ICalendarEvent[]>()
  if (groupBy.value === 'date') {
    for (const ev of sortedEvents.value) {
      const key = ev.start_time.slice(0, 10)
      if (!map.has(key)) map.set(key, [])
      map.get(key)!.push(ev)
    }
    return Array.from(map.entries()).map(([key, events]) => ({
      key,
      label: formatDateLabel(key),
      events,
    }))
  }
  for (const ev of sortedEvents.value) {
    const key = ev.event_type_id ?? 'none'
    if (!map.has(key)) map.set(key, [])
    map.get(key)!.push(ev)
  }
  return Array.from(map.entries()).map(([key, events]) => ({
    key,
    label:
      key === 'none'
        ? '未分类'
        : store.eventTypes.find((t) => t.id === key)?.name ?? '未分类',
    events,
  }))
})

function cardStyle(ev: ICalendarEvent): { borderLeftColor: string } {
  const eventType = store.eventTypes.find((t) => t.id === ev.event_type_id)
  return { borderLeftColor: eventType?.color || '#1677ff' }
}

function formatTime(iso: string): string {
  return new Intl.DateTimeFormat('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
    hour12: false,
  }).format(new Date(iso))
}

function formatDateLabel(dateStr: string): string {
  const date = new Date(dateStr + 'T00:00:00')
  const today = new Date()
  if (date.toDateString() === today.toDateString()) return '今天'
  const tomorrow = new Date(today)
  tomorrow.setDate(tomorrow.getDate() + 1)
  if (date.toDateString() === tomorrow.toDateString()) return '明天'
  return new Intl.DateTimeFormat('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    weekday: 'short',
  }).format(date)
}
</script>

<style scoped>
.card-view {
  height: 100%;
  overflow-y: auto;
  padding: var(--space-3) 0;
}

.card-view__toolbar {
  padding: 0 var(--space-3) var(--space-3);
}

.card-view__empty {
  padding: var(--space-8) 0;
}

.card-view__groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: 0 var(--space-3);
}

.card-view__group-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  font-size: var(--font-sm);
  font-weight: var(--font-weight-medium);
  color: var(--text-secondary);
}

.card-view__cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.card-view__card {
  padding: var(--space-3);
  border: 1px solid var(--border-color);
  border-left: 3px solid #1677ff;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}

.card-view__card:hover {
  background: var(--bg-tertiary);
  border-color: var(--border-color-hover);
}

.card-view__card--invited {
  border-style: dashed;
  background: var(--color-primary-light, rgba(22, 119, 255, 0.06));
}

.card-view__card-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}

.card-view__card-time {
  font-size: var(--font-xs);
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
}

.card-view__card-title {
  font-weight: var(--font-weight-medium);
  color: var(--text-primary);
  margin-bottom: var(--space-1);
}

.card-view__card-location {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--font-xs);
  color: var(--text-tertiary);
}
</style>
