<template>
  <div class="calendar-panel" :class="{ 'calendar-panel--highlight': highlight }">
    <div class="calendar-panel__header">
      <div class="calendar-panel__title">
        <CalendarOutlined />
        <span>日历</span>
        <span class="calendar-panel__date">{{ todayLabel }}</span>
      </div>
      <a-button size="small" type="link" @click="openDrawer">
        <template #icon><ExpandOutlined /></template>
        展开
      </a-button>
    </div>

    <div v-if="store.isLoading && store.events.length === 0" class="calendar-panel__loading">
      <a-spin size="small" />
      <span>加载日程...</span>
    </div>

    <div v-else-if="store.error" class="calendar-panel__error">
      <WarningOutlined />
      <span>{{ store.error }}</span>
    </div>

    <div v-else-if="todayEvents.length === 0 && upcomingEvents.length === 0" class="calendar-panel__empty">
      <CalendarOutlined />
      <span>暂无日程</span>
    </div>

    <div v-else class="calendar-panel__body">
      <div v-if="todayEvents.length > 0" class="calendar-panel__section">
        <div class="calendar-panel__section-title">今日</div>
        <div
          v-for="ev in todayEvents"
          :key="ev.id"
          class="calendar-panel__item"
          :class="{ 'calendar-panel__item--invited': ev.is_invited }"
          @click="onEventClick(ev)"
        >
          <span class="calendar-panel__item-time">{{ formatTime(ev.start_time) }}</span>
          <span class="calendar-panel__item-title">{{ ev.title }}</span>
          <EventBadge :event="ev" />
          <a-tag v-if="ev.is_invited" color="purple" size="small">受邀</a-tag>
        </div>
      </div>

      <div v-if="upcomingEvents.length > 0" class="calendar-panel__section">
        <div class="calendar-panel__section-title">即将到来</div>
        <div
          v-for="ev in upcomingEvents"
          :key="ev.id"
          class="calendar-panel__item"
          :class="{ 'calendar-panel__item--invited': ev.is_invited }"
          @click="onEventClick(ev)"
        >
          <span class="calendar-panel__item-time">{{ formatUpcomingTime(ev.start_time) }}</span>
          <span class="calendar-panel__item-title">{{ ev.title }}</span>
          <EventBadge :event="ev" />
          <a-tag v-if="ev.is_invited" color="purple" size="small">受邀</a-tag>
        </div>
      </div>
    </div>

    <CalendarDrawer
      :open="drawerOpen"
      @update:open="drawerOpen = $event"
      @create="onCreate"
      @edit="onEdit"
      @manage-invitations="onManageInvitations"
    />

    <EventEditor
      v-model:open="editorOpen"
      :event="editorEvent"
      :prefill-start="editorPrefillStart"
      :prefill-end="editorPrefillEnd"
      @saved="onSaved"
    />

    <InvitationManager
      v-model:open="invitationOpen"
      :event="editorEvent"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { CalendarOutlined, ExpandOutlined, WarningOutlined } from '@ant-design/icons-vue'
import { useCalendarStore } from '@/stores/calendar'
import type { ICalendarEvent } from '@/api/calendar'
import EventBadge from './EventBadge.vue'
import CalendarDrawer from './CalendarDrawer.vue'
import EventEditor from './EventEditor.vue'
import InvitationManager from './InvitationManager.vue'

const store = useCalendarStore()

const drawerOpen = ref(false)
const highlight = ref(false)
let highlightTimer: ReturnType<typeof setTimeout> | null = null

// EventEditor state
const editorOpen = ref(false)
const editorEvent = ref<ICalendarEvent | null>(null)
const editorPrefillStart = ref<Date | null>(null)
const editorPrefillEnd = ref<Date | null>(null)

// InvitationManager state
const invitationOpen = ref(false)

const todayLabel = new Intl.DateTimeFormat('zh-CN', {
  month: '2-digit',
  day: '2-digit',
  weekday: 'short',
}).format(new Date())

const todayEvents = computed(() => {
  const now = new Date()
  const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString()
  const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999).toISOString()
  return store.events
    .filter((e) => e.start_time >= startOfDay && e.start_time <= endOfDay)
    .sort((a, b) => a.start_time.localeCompare(b.start_time))
})

const upcomingEvents = computed(() => {
  const now = new Date()
  const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999).toISOString()
  return store.events
    .filter((e) => e.start_time > endOfDay)
    .sort((a, b) => a.start_time.localeCompare(b.start_time))
    .slice(0, 3)
})

// Highlight animation when new event arrives via WS
watch(
  () => store.events.length,
  (newLen, oldLen) => {
    if (newLen > (oldLen ?? 0)) {
      highlight.value = true
      if (highlightTimer) clearTimeout(highlightTimer)
      highlightTimer = setTimeout(() => {
        highlight.value = false
      }, 2000)
    }
  },
)

function openDrawer(): void {
  drawerOpen.value = true
}

function onEventClick(ev: ICalendarEvent): void {
  onEdit(ev)
}

function onCreate(start?: Date, end?: Date): void {
  editorEvent.value = null
  editorPrefillStart.value = start ?? null
  editorPrefillEnd.value = end ?? null
  editorOpen.value = true
}

function onEdit(ev: ICalendarEvent): void {
  editorEvent.value = ev
  editorPrefillStart.value = null
  editorPrefillEnd.value = null
  editorOpen.value = true
}

function onManageInvitations(): void {
  invitationOpen.value = true
}

function onSaved(_event: ICalendarEvent): void {
  // Event already added/updated in store by EventEditor; nothing else needed.
}

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

function formatUpcomingTime(iso: string): string {
  const date = new Date(iso)
  const now = new Date()
  const tomorrow = new Date(now)
  tomorrow.setDate(tomorrow.getDate() + 1)
  if (date.toDateString() === tomorrow.toDateString()) {
    return `明天 ${formatTime(iso)}`
  }
  return new Intl.DateTimeFormat('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    hour12: false,
  }).format(date)
}

onMounted(() => {
  store.loadEvents()
  store.loadEventTypes()
  store.loadTags()
  store.loadInvitations()
})
</script>

<style scoped>
.calendar-panel {
  height: 100%;
  overflow-y: auto;
  padding: var(--space-3) var(--space-4);
  transition: background var(--transition-normal);
}

.calendar-panel--highlight {
  background: var(--color-primary-light, rgba(22, 119, 255, 0.06));
}

.calendar-panel__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-3);
}

.calendar-panel__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-sm);
  font-weight: var(--font-weight-medium);
  color: var(--text-primary);
}

.calendar-panel__date {
  font-size: var(--font-xs);
  color: var(--text-tertiary);
  font-weight: normal;
}

.calendar-panel__loading,
.calendar-panel__error,
.calendar-panel__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-8) 0;
  color: var(--text-tertiary);
  font-size: var(--font-sm);
}

.calendar-panel__error {
  color: var(--color-error);
}

.calendar-panel__section {
  margin-bottom: var(--space-4);
}

.calendar-panel__section-title {
  font-size: var(--font-xs);
  color: var(--text-tertiary);
  margin-bottom: var(--space-2);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.calendar-panel__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--transition-fast);
  margin-bottom: 2px;
}

.calendar-panel__item:hover {
  background: var(--bg-tertiary);
}

.calendar-panel__item--invited {
  border: 1px dashed var(--border-color-hover);
  background: var(--color-primary-light, rgba(22, 119, 255, 0.04));
}

.calendar-panel__item-time {
  font-size: var(--font-xs);
  color: var(--text-tertiary);
  font-variant-numeric: tabular-nums;
  min-width: 48px;
}

.calendar-panel__item-title {
  flex: 1;
  font-size: var(--font-sm);
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
