<script setup lang="ts">
import { ref, computed, onMounted, h } from 'vue'
import { NCard, NButton, NDataTable, NTag, NModal, NForm, NFormItem, NInput, NEmpty, NAlert, NPagination, NDatePicker, NSelect, NSpace, NPopconfirm, NDrawer, NDrawerContent, NTabPane, NTabs, NIcon, NSkeleton, NGrid, NGridItem, NStatistic, type FormRules } from 'naive-ui'
import { AddOutline, SaveOutline } from '@vicons/ionicons5'
import { api } from '../../api/client'
import { useToast } from '../../composables/useToast'
import { useAuthStore } from '../../stores/auth'

interface JournalClubItem {
  id: string
  title: string
  journal: string
  scheduled_date: string | null
  status: string
  pmid: number
  presenter_id: string | null
  discussion_notes: string | null
  suggested_by: string
  created_at: string
  [key: string]: unknown
}

interface TeamMember {
  id: string
  display_name: string
  email: string
  title: string | null
  role: string
}

const toast = useToast()
const queue = ref<JournalClubItem[]>([])
const archive = ref<JournalClubItem[]>([])
const loading = ref(true)
const members = ref<TeamMember[]>([])
const activeTab = ref('queue')

// ── Stats ──
const stats = ref({ queued_count: 0, presented_this_month: 0, total_archived: 0, monthly_counts: [] as { month: string; count: number }[], top_presenters: [] as { presenter_id: string; display_name: string; count: number }[] })

// ── Attendance ──
const showAttendance = ref(false)
const attendItem = ref<JournalClubItem | null>(null)
const attendees = ref<any[]>([])
const attendLoading = ref(false)
const attendComment = ref('')
const attendRating = ref<number | null>(null)
const attendSaving = ref(false)

// ── Add modal ──
const addLoading = ref(false)
const showAdd = ref(false)
const addMode = ref<'single' | 'batch'>('single')
const form = ref({ literature_pmid: '', title: '', scheduled_date: null as string | null, presenter_id: '' as string })
const singleFormRef = ref()
const singleRules: FormRules = {
  literature_pmid: [
    { required: true, message: '请输入 PMID', trigger: 'blur' },
    { pattern: /^\d+$/, message: 'PMID 必须为数字', trigger: 'blur' },
  ],
}
const batchPmids = ref('')

// ── AI outline ──
const aiOutline = ref('')
const outlineLoading = ref(false)
const lastOutlinePmid = ref(0)

// ── Archive pagination ──
const archivePage = ref(1)
const archivePageSize = ref(20)
const archiveTotal = ref(0)

// ── Notes editing ──
const notesDrawer = ref(false)
const editingNotes = ref('')
const editingItem = ref<JournalClubItem | null>(null)
const notesSaving = ref(false)

// ── Presenter options ──
const presenterOptions = computed(() =>
  members.value.map((m: TeamMember) => ({ label: `${m.display_name}${m.title ? ` (${m.title})` : ''}`, value: m.id }))
)

// ── Calendar view ──
const calendarMonth = ref(new Date().getMonth())
const calendarYear = ref(new Date().getFullYear())

// ── Preread ──
const showPreread = ref(false)
const prereadPmid = ref(0)
const prereadData = ref<any[]>([])
const prereadLoading = ref(false)
const prereadSource = ref('')

const scheduledItems = computed(() => {
  return [...queue.value, ...archive.value].filter((i: JournalClubItem) => i.scheduled_date)
})

const calendarDays = computed(() => {
  const year = calendarYear.value
  const month = calendarMonth.value
  const firstDay = new Date(year, month, 1).getDay()
  const daysInMonth = new Date(year, month + 1, 0).getDate()
  const days: { date: string; day: number; items: JournalClubItem[] }[] = []

  for (let i = 0; i < firstDay; i++) {
    days.push({ date: '', day: 0, items: [] })
  }
  for (let d = 1; d <= daysInMonth; d++) {
    const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`
    const items = scheduledItems.value.filter((i: JournalClubItem) => i.scheduled_date === dateStr)
    days.push({ date: dateStr, day: d, items })
  }
  return days
})

function prevMonth() {
  if (calendarMonth.value === 0) { calendarMonth.value = 11; calendarYear.value-- }
  else calendarMonth.value--
}
function nextMonth() {
  if (calendarMonth.value === 11) { calendarMonth.value = 0; calendarYear.value++ }
  else calendarMonth.value++
}

const monthLabel = computed(() => {
  return `${calendarYear.value} 年 ${calendarMonth.value + 1} 月`
})

// ── Load data ──
const auth = useAuthStore()

onMounted(() => {
  currentUserId.value = auth.user?.id || ''
  loadData()
})

async function loadData() {
  loading.value = true
  try {
    const [qRes, aRes, mRes, sRes] = await Promise.all([
      api.get('/journal-club/queue'),
      api.get('/journal-club/archive', { params: { page: archivePage.value, page_size: archivePageSize.value } }),
      api.get('/teams/members'),
      api.get('/journal-club/stats'),
    ])
    queue.value = qRes.data.items || []
    archive.value = aRes.data.items || []
    archiveTotal.value = aRes.data.total || 0
    members.value = mRes.data.members || []
    stats.value = sRes.data || stats.value
  } catch (e) { toast.apiError(e, '加载数据失败') }
  finally { loading.value = false }
}

// ── Attendance ──
async function loadAttendance(item: JournalClubItem) {
  attendItem.value = item
  attendLoading.value = true
  try {
    const { data } = await api.get(`/journal-club/queue/${item.id}/attendance`)
    attendees.value = data.attendees || []
  } catch (e) { /* silent */ }
  finally { attendLoading.value = false }
  showAttendance.value = true
}
async function signIn() {
  attendSaving.value = true
  try {
    await api.post(`/journal-club/queue/${attendItem.value!.id}/attendance`, { rating: attendRating.value, comment: attendComment.value || null })
    toast.success('已签到')
    attendComment.value = ''
    attendRating.value = null
    loadAttendance(attendItem.value!)
  } catch (e) { toast.apiError(e, '签到失败') }
  finally { attendSaving.value = false }
}
async function signOut(itemId: string) {
  try {
    await api.delete(`/journal-club/queue/${itemId}/attendance`)
    toast.success('已取消')
    loadAttendance(attendItem.value!)
  } catch (e) { toast.apiError(e, '取消签到失败') }
}
function isSignedIn(): boolean {
  return attendees.value.some(a => a.user_id === currentUserId)
}
const currentUserId = ref('')

// ── Calendar day click ──
const showDayItems = ref(false)
const selectedDay = ref('')
const selectedDayItems = ref<JournalClubItem[]>([])
function clickCalendarDay(day: { date: string; day: number; items: JournalClubItem[] }) {
  if (!day.date) return
  selectedDay.value = day.date
  selectedDayItems.value = day.items
  showDayItems.value = true
}

// ── AI outline save to notes ──
async function saveOutlineAsNotes(item: JournalClubItem) {
  try {
    await api.post(`/journal-club/queue/${item.id}/notes`, { discussion_notes: aiOutline.value })
    toast.success('提纲已保存到笔记')
    aiOutline.value = ''
  } catch (e) { toast.apiError(e, '保存失败') }
}

// ── Add to queue ──
async function addToQueue() {
  addLoading.value = true
  try {
    if (addMode.value === 'batch') {
      const pmids = batchPmids.value.split(/[\s,，]+/).filter(Boolean)
      if (!pmids.length) { toast.warning('请输入 PMID'); return }
      const succeeded: string[] = []
      const failed: { pmid: string; reason: string }[] = []
      for (const pmid of pmids) {
        try {
          await api.post('/journal-club/queue', { literature_pmid: Number(pmid), title: '', scheduled_date: null, presenter_id: '' })
          succeeded.push(pmid)
        } catch (e: any) {
          const detail = e?.response?.data?.detail || ''
          failed.push({ pmid, reason: detail || '添加失败' })
        }
      }
      if (succeeded.length) toast.success(`已添加 ${succeeded.length} 篇`)
      if (failed.length) {
        failed.forEach(f => toast.warning(`PMID ${f.pmid}：${f.reason}`))
      }
    } else {
      try { await singleFormRef.value?.validate() } catch { return }
      await api.post('/journal-club/queue', { ...form.value, literature_pmid: Number(form.value.literature_pmid) })
      toast.success('已添加到排队')
    }
    showAdd.value = false
    loadData()
  } catch (e: any) {
    toast.apiError(e, '添加失败')
  } finally { addLoading.value = false }
}

async function markPresented(row: JournalClubItem) {
  try {
    await api.post(`/journal-club/queue/${row.id}/decide`, { status: 'presented', discussion_notes: '' })
    loadData()
  } catch (e) { toast.apiError(e, '标记失败') }
}

async function skipArticle(row: JournalClubItem) {
  try {
    await api.post(`/journal-club/queue/${row.id}/decide`, { status: 'skipped' })
    loadData()
  } catch (e) { toast.apiError(e, '跳过失败') }
}

async function deleteArticle(row: JournalClubItem) {
  try {
    await api.delete(`/journal-club/queue/${row.id}`)
    toast.success('已删除')
    loadData()
  } catch (e) { toast.apiError(e, '删除失败') }
}

async function updateItem(id: string, data: { scheduled_date?: string | null; presenter_id?: string | null }) {
  try {
    await api.patch(`/journal-club/queue/${id}`, data)
  } catch (e) { toast.apiError(e, '更新失败') }
}

async function loadPreread(pmid: number) {
  prereadPmid.value = pmid
  prereadLoading.value = true
  prereadData.value = []
  try {
    const { data } = await api.get(`/journal-club/preread/${pmid}`)
    prereadData.value = data.items || []
    prereadSource.value = data.source || ''
  } catch (e) { toast.apiError(e, '加载推荐失败') }
  finally {
    prereadLoading.value = false
    showPreread.value = true
  }
}

async function genOutline(pmid: number) {
  outlineLoading.value = true
  aiOutline.value = ''
  lastOutlinePmid.value = pmid
  try {
    const { data } = await api.get(`/journal-club/ai-outline/${pmid}`)
    aiOutline.value = data.outline || '生成成功'
  } catch { aiOutline.value = 'AI 生成失败' }
  finally { outlineLoading.value = false }
}

// ── Notes editing ──
function openNotes(item: JournalClubItem) {
  editingItem.value = item
  editingNotes.value = item.discussion_notes || ''
  notesDrawer.value = true
}
async function saveNotes() {
  if (!editingItem.value) return
  notesSaving.value = true
  try {
    await api.post(`/journal-club/queue/${editingItem.value.id}/notes`, { discussion_notes: editingNotes.value })
    toast.success('笔记已保存')
    notesDrawer.value = false
    loadData()
  } catch (e) { toast.apiError(e, '保存失败') }
  finally { notesSaving.value = false }
}

// ── Columns ──
const actionCols = (isArchive: boolean) => [
  { title: '文献', key: 'title', ellipsis: { tooltip: true }, maxWidth: 260, render: (r: JournalClubItem) => h('a', {
      href: `/app/literature/${r.pmid}`,
      onClick: (e: Event) => { e.preventDefault(); window.open(`/app/literature/${r.pmid}`, '_blank') },
      style: 'color:#1a5276;text-decoration:none;cursor:pointer',
    }, r.title?.slice(0, 60)) },
  { title: '期刊', key: 'journal', width: 90, ellipsis: true },
  { title: '日期', key: 'scheduled_date', width: 150, render: (r: JournalClubItem) => {
      if (isArchive) return r.scheduled_date || '—'
      return h('div', { style: 'display:flex;align-items:center' }, [
        h(NDatePicker as any, {
          value: r.scheduled_date ? new Date(r.scheduled_date).getTime() : null,
          type: 'date',
          placeholder: '选择日期',
          size: 'tiny',
          style: 'width:130px',
          'onUpdate:value': (val: number | null) => {
            const dateStr = val ? new Date(val).toISOString().slice(0, 10) : null
            updateItem(r.id, { scheduled_date: dateStr })
            r.scheduled_date = dateStr
          },
        }),
      ])
    }
  },
  { title: '汇报人', key: 'presenter', width: 130, render: (r: JournalClubItem) => {
      if (isArchive) {
        if (!r.presenter_id) return null
        const m = members.value.find((x: TeamMember) => x.id === r.presenter_id)
        return m ? m.display_name : '—'
      }
      return h(NSelect, {
        value: r.presenter_id || null,
        options: presenterOptions.value,
        placeholder: '分配',
        size: 'tiny',
        clearable: true,
        style: 'width:120px',
        'onUpdate:value': async (val: string | null) => {
          try {
            await api.patch(`/journal-club/queue/${r.id}`, { presenter_id: val || null })
            r.presenter_id = val || null
          } catch (e) { toast.apiError(e, '分配失败') }
        },
      })
    }
  },
  { title: '状态', key: 'status', width: 55, render: (r: JournalClubItem) =>
      h(NTag, { size: 'tiny', type: r.status === 'queued' ? 'warning' : r.status === 'presented' ? 'success' : 'default' },
        r.status === 'queued' ? '排队' : r.status === 'presented' ? '完成' : '跳过')
  },
  { title: '操作', key: 'actions', width: 270, render: (r: JournalClubItem) => {
      if (isArchive && r.status === 'presented') {
        return h('div', { style: 'display:flex;gap:4px;flex-wrap:wrap' }, [
          h(NButton, { size: 'tiny', secondary: true, onClick: () => openNotes(r) }, '📝 笔记'),
          h(NButton, { size: 'tiny', secondary: true, onClick: () => loadAttendance(r) }, '✅ 签到'),
        ])
      }
      if (r.status !== 'queued') return null
      return h('div', { style: 'display:flex;gap:4px;flex-wrap:wrap' }, [
        h(NButton, { size: 'tiny', type: 'primary', onClick: () => markPresented(r) }, '已完成'),
        h(NButton, { size: 'tiny', onClick: () => skipArticle(r) }, '跳过'),
        h(NButton, { size: 'tiny', secondary: true, onClick: () => genOutline(r.pmid) }, 'AI提纲'),
        h(NButton, { size: 'tiny', quaternary: true, onClick: () => loadPreread(r.pmid) }, '📖 必读'),
        h(NPopconfirm, { onPositiveClick: () => deleteArticle(r) }, {
          default: () => '确定删除?',
          trigger: () => h(NButton, { size: 'tiny', quaternary: true }, '🗑'),
        }),
      ])
    }
  },
]

const jcScrollX = 955
</script>

<template>
  <div class="jc-root" style="max-width:1400px;margin:0 auto;padding:24px">
    <div class="jc-header" style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
      <h2 style="margin:0">📋 Journal Club</h2>
      <NSpace>
        <NButton @click="showAdd=true" size="small" class="sky-btn"><template #icon><NIcon size="14"><AddOutline /></NIcon></template>添加文献</NButton>
      </NSpace>
    </div>
    <NAlert type="info" style="margin-bottom:16px" title="科室文献汇报管理 — 添加文献到排队，安排汇报人，AI 自动生成汇报提纲" />

    <!-- Stats cards -->
    <n-grid :cols="4" :x-gap="12" responsive="screen" style="margin-bottom:16px">
      <n-grid-item><NCard size="small"><n-statistic label="待汇报" :value="stats.queued_count" /></NCard></n-grid-item>
      <n-grid-item><NCard size="small"><n-statistic label="本月汇报" :value="stats.presented_this_month" /></NCard></n-grid-item>
      <n-grid-item><NCard size="small"><n-statistic label="总归档" :value="stats.total_archived" /></NCard></n-grid-item>
      <n-grid-item><NCard size="small">
        <n-statistic label="热门汇报人" :value="stats.top_presenters[0]?.display_name || '—'" />
        <div v-if="stats.top_presenters.length" style="font-size:11px;color:var(--text-muted);margin-top:4px">
          <span v-for="(p,i) in stats.top_presenters.slice(0,3)" :key="p.presenter_id">
            {{ i ? ' · ' : '' }}{{ p.display_name }}({{ p.count }})
          </span>
        </div>
      </NCard></n-grid-item>
    </n-grid>

    <NTabs v-model:value="activeTab" type="line">
      <NTabPane name="queue" tab="📥 待汇报">
        <NCard size="small" class="jc-table-card" style="margin-bottom:16px">
          <NEmpty v-if="!loading && !queue.filter(i => i.status === 'queued').length" description="暂无排队文献" />
          <NDataTable v-else :columns="actionCols(false)" :data="queue.filter(i => i.status === 'queued')" size="small" :bordered="false" :loading="loading" :scroll-x="jcScrollX" />
        </NCard>

        <!-- AI 大纲 -->
        <NCard v-if="aiOutline" size="small" style="margin-top:12px;background:var(--bg-card)">
          <template #header><span style="font-size:13px;font-weight:600">🤖 AI 生成提纲</span></template>
          <div style="font-size:13px;line-height:1.7;white-space:pre-wrap">{{ aiOutline }}</div>
          <template #footer><NSpace><NButton class="sky-btn" size="tiny" @click="aiOutline=''">关闭</NButton><NButton class="sky-btn" size="tiny" type="primary" @click="() => { const q = queue.find(i => i.pmid === lastOutlinePmid); if (q) saveOutlineAsNotes(q); }">💾 保存到笔记</NButton></NSpace></template>
        </NCard>
      </NTabPane>

      <NTabPane name="archive" tab="📦 历史归档">
        <NCard size="small" class="jc-table-card" style="margin-bottom:16px">
          <NDataTable v-if="archive.length" :columns="actionCols(true)" :data="archive" size="small" :bordered="false" :scroll-x="jcScrollX" />
          <NEmpty v-else description="暂无归档" />
          <div v-if="archiveTotal > archivePageSize" style="display:flex;justify-content:center;margin-top:16px">
            <NPagination :page="archivePage" :page-size="archivePageSize" :item-count="archiveTotal" @update:page="p => { archivePage=p; loadData() }" />
          </div>
        </NCard>
      </NTabPane>

      <NTabPane name="calendar" tab="📅 排期日历">
        <NCard size="small">
          <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
            <NButton class="sky-btn" size="tiny" @click="prevMonth">‹ 上月</NButton>
            <strong>{{ monthLabel }}</strong>
            <NButton class="sky-btn" size="tiny" @click="nextMonth">下月 ›</NButton>
          </div>
          <div class="cal-grid">
            <div class="cal-header" v-for="d in ['日','一','二','三','四','五','六']" :key="d">{{ d }}</div>
            <div v-for="(day, i) in calendarDays" :key="i" class="cal-cell"
              :class="{ 'cal-empty': !day.day, 'cal-today': day.date === new Date().toISOString().slice(0,10), 'cal-has-items': day.items.length > 0 }"
              @click="clickCalendarDay(day)">
              <div v-if="day.day" class="cal-day">{{ day.day }}</div>
              <div v-for="item in day.items.slice(0,3)" :key="item.id" class="cal-item" :class="item.status">
                <span class="cal-item-title">{{ item.title?.slice(0, 12) }}</span>
              </div>
              <div v-if="day.items.length > 3" class="cal-more">+{{ day.items.length - 3 }} 更多</div>
            </div>
          </div>
        </NCard>
      </NTabPane>
    </NTabs>

    <!-- Add Modal -->
    <NModal v-model:show="showAdd" title="添加文献到 Journal Club" preset="card" style="width:520px" class="jc-modal" scrollable>
      <NSpace style="margin-bottom:12px">
        <NButton class="sky-btn" :type="addMode==='single'?'primary':'default'" size="small" @click="addMode='single'"><template #icon><NIcon size="14"><AddOutline /></NIcon></template>单篇添加</NButton>
        <NButton class="sky-btn" :type="addMode==='batch'?'primary':'default'" size="small" @click="addMode='batch'"><template #icon><NIcon size="14"><AddOutline /></NIcon></template>批量添加</NButton>
      </NSpace>

      <template v-if="addMode==='single'">
        <NForm ref="singleFormRef" :model="form" :rules="singleRules" label-placement="left" label-width="80">
          <NFormItem path="literature_pmid" label="PMID"><NInput v-model:value="form.literature_pmid" placeholder="e.g. 39000101" /></NFormItem>
          <NFormItem label="标题"><NInput v-model:value="form.title" placeholder="可选" /></NFormItem>
          <NFormItem label="排期">
            <NDatePicker :value="form.scheduled_date ? new Date(form.scheduled_date).getTime() : null" type="date" placeholder="选择日期" style="width:100%" @update:value="(val: number | null) => form.scheduled_date = val ? new Date(val).toISOString().slice(0, 10) : null" />
          </NFormItem>
          <NFormItem label="汇报人">
            <NSelect v-model:value="form.presenter_id" :options="presenterOptions" placeholder="选择汇报人" clearable />
          </NFormItem>
          <NButton class="sky-btn" type="primary" block :loading="addLoading" @click="addToQueue"><template #icon><NIcon size="14"><AddOutline /></NIcon></template>添加到排队</NButton>
        </NForm>
      </template>
      <template v-else>
        <div style="margin-bottom:8px;font-size:13px;color:var(--text-secondary)">输入 PMID，用逗号/空格分隔</div>
        <NInput v-model:value="batchPmids" type="textarea" placeholder="39000101, 39000102, 39000103" :rows="4" />
        <NButton class="sky-btn" type="primary" block style="margin-top:12px" :loading="addLoading" @click="addToQueue"><template #icon><NIcon size="14"><AddOutline /></NIcon></template>批量添加</NButton>
      </template>
    </NModal>

    <!-- Notes Drawer -->
    <NDrawer v-model:show="notesDrawer" :width="400" placement="right">
      <NDrawerContent title="📝 讨论笔记" closable>
        <template v-if="editingItem">
          <div style="margin-bottom:12px;font-size:13px;color:var(--text-secondary)">
            <strong>{{ editingItem.title }}</strong>
            <div style="margin-top:4px">{{ editingItem.journal }} · PMID: {{ editingItem.pmid }}</div>
          </div>
          <NInput v-model:value="editingNotes" type="textarea" :rows="10" placeholder="记录讨论内容..." />
          <NButton class="sky-btn" type="primary" block style="margin-top:16px" :loading="notesSaving" @click="saveNotes"><template #icon><NIcon size="14"><SaveOutline /></NIcon></template>保存笔记</NButton>
        </template>
      </NDrawerContent>
    </NDrawer>

    <!-- Preread Drawer -->
    <NDrawer v-model:show="showPreread" :width="460" placement="right">
      <NDrawerContent title="📖 读前必读" closable>
        <template v-if="prereadLoading">
          <div v-for="i in 3" :key="i" style="padding:12px 0;border-bottom:1px solid var(--border-color)">
            <div style="height:14px;background:var(--border-color);border-radius:4px;width:70%;margin-bottom:8px"></div>
            <div style="height:12px;background:var(--border-color);border-radius:4px;width:40%;margin-bottom:4px"></div>
            <div style="height:12px;background:var(--border-color);border-radius:4px;width:50%"></div>
          </div>
        </template>
        <template v-else-if="prereadData.length">
          <div style="font-size:12px;color:var(--text-muted);margin-bottom:12px">
            PMID: {{ prereadPmid }} · 来源: {{ prereadSource === 'tags' ? '标签重叠' : prereadSource === 'journal' ? '同期刊' : '—' }}
          </div>
          <div v-for="(item, i) in prereadData" :key="i"
               style="padding:12px;border:1px solid var(--border-color);border-radius:8px;margin-bottom:10px;background:var(--bg-card)">
            <div style="font-size:13px;font-weight:600;margin-bottom:4px;line-height:1.4">
              <a :href="'https://pubmed.ncbi.nlm.nih.gov/'+item.pmid+'/'" target="_blank" rel="noopener" style="color:#1a5276;text-decoration:none">
                {{ item.title?.slice(0, 60) }}
              </a>
            </div>
            <div style="font-size:12px;color:var(--text-secondary);margin-bottom:6px">
              {{ item.first_author }} · {{ item.journal }}
              <span v-if="item.pub_date"> · {{ (item.article_date || item.pub_date).slice(0,10) }}</span>
            </div>
            <div style="display:flex;gap:8px;font-size:11px">
              <NTag v-if="item.cited_by_count" size="tiny" :bordered="false">📊 被引 {{ item.cited_by_count }}</NTag>
              <NTag v-if="item.overlap_tags" size="tiny" type="info" :bordered="false">🏷 共享 {{ item.overlap_tags }} 标签</NTag>
              <NTag v-if="item.relevance_score" size="tiny" type="success" :bordered="false">⭐ 相关度 {{ item.relevance_score }}</NTag>
            </div>
          </div>
        </template>
        <div v-else style="text-align:center;padding:40px;color:var(--text-muted);font-size:13px">暂无推荐文献</div>
      </NDrawerContent>
    </NDrawer>

    <!-- Attendance Modal -->
    <NModal v-model:show="showAttendance" title="✅ 参会签到" preset="card" style="width:450px" closable>
      <template v-if="attendItem">
        <div style="margin-bottom:12px;font-size:13px;color:var(--text-secondary)">
          <strong>{{ attendItem.title }}</strong>
        </div>
        <NSkeleton v-if="attendLoading" text :repeat="3" />
        <template v-else>
          <div v-if="attendees.length" style="margin-bottom:12px">
            <div style="font-size:12px;font-weight:600;color:var(--text-secondary);margin-bottom:6px">已签到成员</div>
            <div v-for="a in attendees" :key="a.id" style="display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border:1px solid var(--border-color);border-radius:6px;margin-bottom:4px">
              <div style="display:flex;align-items:center;gap:8px">
                <span style="font-size:13px">{{ a.display_name }}</span>
                <NTag v-if="a.rating" size="tiny" type="success" :bordered="false">⭐ {{ a.rating }}</NTag>
              </div>
              <div style="display:flex;gap:4px;align-items:center">
                <span v-if="a.comment" style="font-size:11px;color:var(--text-muted);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">{{ a.comment }}</span>
                <NButton v-if="a.user_id === currentUserId" size="tiny" text type="error" @click="signOut(a.queue_id || attendItem.id)">取消</NButton>
              </div>
            </div>
          </div>
          <div v-if="!isSignedIn()" style="margin-top:12px">
            <div style="font-size:12px;font-weight:600;color:var(--text-secondary);margin-bottom:6px">签到</div>
            <div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:8px">
              <span v-for="s in [1,2,3,4,5]" :key="s" class="star-btn" :class="{ active: attendRating === s }"
                @click="attendRating = attendRating === s ? null : s">⭐{{ s }}</span>
            </div>
            <NInput v-model:value="attendComment" placeholder="评论（可选）" size="small" />
            <NButton class="sky-btn" type="primary" block size="small" style="margin-top:8px" :loading="attendSaving" @click="signIn">✅ 签到</NButton>
          </div>
          <div v-else style="margin-top:8px;padding:8px;background:var(--bg-hover);border-radius:6px;text-align:center;font-size:13px;color:var(--text-secondary)">
            ✅ 你已签到
          </div>
        </template>
      </template>
    </NModal>

    <!-- Day items modal -->
    <NModal v-model:show="showDayItems" :title="selectedDay" preset="card" style="width:500px" closable>
      <div v-if="!selectedDayItems.length" style="text-align:center;padding:24px;color:var(--text-muted)">当天无安排</div>
      <div v-for="item in selectedDayItems" :key="item.id" style="padding:10px 0;border-bottom:1px solid var(--border-color);display:flex;justify-content:space-between;align-items:flex-start">
        <div style="flex:1;margin-right:8px">
          <div style="font-size:13px;font-weight:500;margin-bottom:2px">
            <a :href="'/app/literature/'+item.pmid" target="_blank" style="color:#1a5276;text-decoration:none">{{ item.title?.slice(0, 50) }}</a>
          </div>
          <div style="font-size:11px;color:var(--text-muted)">
            {{ item.journal }} · PMID: {{ item.pmid }}
            <span v-if="item.presenter_id"> · {{ members.find(m => m.id === item.presenter_id)?.display_name || '' }}</span>
          </div>
        </div>
        <NTag size="tiny" :type="item.status === 'presented' ? 'success' : 'warning'" :bordered="false">
          {{ item.status === 'presented' ? '已汇报' : '待汇报' }}
        </NTag>
      </div>
    </NModal>
  </div>
</template>

<style scoped>
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.cal-header {
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  padding: 6px 0;
}
.cal-cell {
  min-height: 70px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  padding: 4px;
  position: relative;
}
.cal-empty {
  border-color: transparent;
  background: transparent;
}
.cal-today {
  border-color: #1a5276;
  background: var(--bg-hover);
}
.cal-day {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 3px;
}
.cal-item {
  font-size: 10px;
  line-height: 1.3;
  padding: 1px 4px;
  border-radius: 3px;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: default;
}
.cal-item.queued { background: transparent; color: var(--text-secondary); }
.cal-item.presented { background: transparent; color: var(--text-primary); }
.cal-item-title { font-size: 10px; }
.cal-more {
  font-size: 10px;
  color: var(--text-muted);
  text-align: center;
}

.cal-has-items { cursor: pointer; }
.cal-has-items:hover { background: var(--bg-hover); }

.star-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 28px; border: 1px solid var(--border-color);
  border-radius: 4px; font-size: 12px; cursor: pointer;
  background: var(--bg-card);
}
.star-btn:hover { border-color: var(--primary-color); }
.star-btn.active { border-color: var(--primary-color); background: var(--primary-color); color: #fff; }

@media (max-width: 768px) {
  .jc-root {
    padding: 16px !important;
  }
  .jc-header {
    flex-wrap: wrap;
    gap: 8px;
  }
  .jc-header h2 {
    font-size: 20px;
  }
  .jc-table-card {
    overflow-x: auto;
  }
  .jc-modal :deep(.n-card) {
    width: 100% !important;
  }
  .cal-cell {
    min-height: 50px;
    padding: 2px;
  }
  .cal-header {
    font-size: 11px;
    padding: 4px 0;
  }
}
</style>
