<template>
  <div class="research-list-page">
    <section class="list-header">
      <div class="list-header__main">
        <div class="list-header__meta">
          <span>共 {{ store.total }} 条</span>
          <span>{{ store.showArchived ? '归档视图' : '活跃视图' }}</span>
        </div>
      </div>
      <div class="list-header__actions">
        <a-button type="primary" @click="router.push('/research/new')">新建研究</a-button>
      </div>
    </section>

    <section class="filter-panel">
      <div class="list-filters">
        <a-input
          v-model:value="store.searchQuery"
          placeholder="搜索标题或主题"
          class="filter-input filter-input--search"
          allow-clear
          @change="debouncedLoad"
        >
          <template #prefix><SearchOutlined class="filter-input__icon" /></template>
        </a-input>
        <a-select
          v-model:value="store.statusFilter"
          placeholder="全部状态"
          class="filter-input"
          allow-clear
          @change="doLoad"
        >
          <a-select-option value="draft">草稿</a-select-option>
          <a-select-option value="planned">已规划</a-select-option>
          <a-select-option value="running">研究中</a-select-option>
          <a-select-option value="completed">已完成</a-select-option>
          <a-select-option value="failed">失败</a-select-option>
        </a-select>
        <a-select
          v-model:value="store.modeFilter"
          placeholder="全部模式"
          class="filter-input"
          allow-clear
          @change="doLoad"
        >
          <a-select-option value="quick">快速</a-select-option>
          <a-select-option value="deep">深入</a-select-option>
        </a-select>
        <a-select
          v-model:value="store.templateFilter"
          placeholder="全部模板"
          class="filter-input filter-input--template"
          allow-clear
          @change="doLoad"
        >
          <a-select-option v-for="t in templateOptions" :key="t.value" :value="t.value">
            {{ t.label }}
          </a-select-option>
        </a-select>
        <a-range-picker
          :value="store.timeRange"
          class="filter-input filter-input--date"
          :placeholder="['开始日期', '结束日期']"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          allow-clear
          @change="handleTimeRangeChange"
        />
        <a-select
          v-model:value="store.sortBy"
          class="filter-input"
          @change="doLoad"
        >
          <a-select-option value="updated_at">按更新时间</a-select-option>
          <a-select-option value="created_at">按创建时间</a-select-option>
        </a-select>
        <a-button
          size="small"
          @click="toggleSortOrder"
          style="min-width: 32px"
        >
          {{ store.sortOrder === 'desc' ? '↓' : '↑' }}
        </a-button>
        <div class="filter-panel__switch">
          <span class="filter-panel__switch-label">{{ store.showArchived ? '归档视图' : '活跃视图' }}</span>
          <a-switch
            v-model:checked="store.showArchived"
            checked-children="已归档"
            un-checked-children="活跃"
            @change="doLoad"
          />
        </div>
        <div class="filter-panel__actions">
          <a-button @click="resetFilters">重置筛选</a-button>
        </div>
      </div>
    </section>

    <div v-if="store.loading" class="list-loading">
      <a-spin size="large" />
    </div>

    <a-empty
      v-else-if="store.records.length === 0"
      class="list-empty"
      description="暂无符合条件的研究记录"
    >
      <a-button type="primary" @click="router.push('/research/new')">创建第一个研究</a-button>
    </a-empty>

    <section v-else class="record-list">
      <article
        v-for="record in store.records"
        :key="record.id"
        class="record-card"
        @click="router.push(`/research/${record.id}`)"
      >
        <div class="record-card__glow"></div>
        <div class="record-card__header">
          <div class="record-card__title-row">
            <h3 class="record-card__title">{{ record.title }}</h3>
          </div>
          <div class="record-card__meta">
            <a-tag :color="statusColor(record.status)" class="record-card__status" :bordered="false" size="small">
              {{ statusLabel(record.status) }}
            </a-tag>
            <a-tag :color="record.mode === 'quick' ? 'green' : 'blue'" :bordered="false" size="small">
              {{ record.mode === 'quick' ? '快速研究' : '深度研究' }}
            </a-tag>
            <a-tag :bordered="false" size="small">{{ templateLabel(record.outputTemplate) }}</a-tag>
            <span class="record-card__time">{{ formatTime(record.updatedAt) }}</span>
          </div>
        </div>

        <div class="record-card__summary-shell">
          <div class="record-card__summary">{{ record.summary || '当前记录尚未生成摘要，可进入详情查看计划与执行状态。' }}</div>
        </div>

        <div class="record-card__footer" @click.stop>
          <div class="record-card__info">
            <span class="record-card__version">{{ record.versionNo > 1 ? `v${record.versionNo}` : '首个版本' }}</span>
            <span class="record-card__created">创建于 {{ formatAbsoluteTime(record.createdAt) }}</span>
          </div>
          <div class="record-card__actions">
            <a-button size="small" type="link" @click="router.push(`/research/${record.id}`)">查看详情</a-button>
            <a-popconfirm
              v-if="!record.archived"
              title="确定归档此记录？"
              @confirm="store.archiveRecord(record.id)"
            >
              <a-button size="small" type="link">归档</a-button>
            </a-popconfirm>
            <a-popconfirm
              v-if="canDelete(record.status)"
              title="确定删除此记录？删除后不可恢复。"
              @confirm="store.removeRecord(record.id)"
            >
              <a-button size="small" type="link" danger>删除</a-button>
            </a-popconfirm>
          </div>
        </div>
      </article>
    </section>

    <div v-if="store.total > store.pageSize" class="list-pagination">
      <a-pagination
        :current="store.page"
        :page-size="store.pageSize"
        :total="store.total"
        show-size-changer
        :show-total="(t: number) => `共 ${t} 条`"
        @change="handlePageChange"
        @show-size-change="handleSizeChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { SearchOutlined } from '@ant-design/icons-vue'
import { useResearchRecordListStore } from '@/stores/researchRecordList'
import { RESEARCH_TEMPLATE_OPTIONS } from '@/types/research'

const router = useRouter()
const store = useResearchRecordListStore()

const templateOptions = RESEARCH_TEMPLATE_OPTIONS.map((t) => ({
  value: t.value,
  label: t.label,
}))

onMounted(() => store.loadRecords())

let debounceTimer: ReturnType<typeof setTimeout> | null = null
function debouncedLoad() {
  if (debounceTimer) clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => {
    store.page = 1
    store.loadRecords()
  }, 300)
}

function doLoad() {
  store.page = 1
  store.loadRecords()
}

function handlePageChange(page: number) {
  store.page = page
  store.loadRecords()
}

function handleSizeChange(_current: number, size: number) {
  store.pageSize = size
  store.page = 1
  store.loadRecords()
}

function handleTimeRangeChange(dates: [string, string] | null) {
  store.timeRange = dates
  store.page = 1
  store.loadRecords()
}

function toggleSortOrder() {
  store.sortOrder = store.sortOrder === 'desc' ? 'asc' : 'desc'
  store.page = 1
  store.loadRecords()
}

function resetFilters() {
  store.searchQuery = ''
  store.statusFilter = null
  store.modeFilter = null
  store.templateFilter = null
  store.timeRange = null
  store.sortBy = 'updated_at'
  store.sortOrder = 'desc'
  store.showArchived = false
  store.page = 1
  store.loadRecords()
}

function templateLabel(value: string) {
  return RESEARCH_TEMPLATE_OPTIONS.find((t) => t.value === value)?.label || value || '默认报告'
}

function statusColor(status: string) {
  const map: Record<string, string> = {
    draft: 'default', planned: 'blue', running: 'orange',
    completed: 'green', failed: 'red', cancelled: 'gray',
  }
  return map[status] || 'default'
}

function statusLabel(status: string) {
  const map: Record<string, string> = {
    draft: '草稿', clarifying: '澄清中', planned: '已规划',
    running: '研究中', completed: '已完成', failed: '失败', cancelled: '已中断',
  }
  return map[status] || status
}

function canDelete(status: string) {
  return ['draft', 'planned', 'failed'].includes(status)
}

function formatTime(timeStr: string) {
  if (!timeStr) return ''
  try {
    const d = new Date(timeStr)
    const now = new Date()
    const diffMs = now.getTime() - d.getTime()
    const diffMin = Math.floor(diffMs / 60000)
    if (diffMin < 1) return '刚刚'
    if (diffMin < 60) return `${diffMin} 分钟前`
    const diffHour = Math.floor(diffMin / 60)
    if (diffHour < 24) return `${diffHour} 小时前`
    const diffDay = Math.floor(diffHour / 24)
    if (diffDay < 7) return `${diffDay} 天前`
    return d.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric' })
  } catch {
    return timeStr
  }
}

function formatAbsoluteTime(timeStr: string) {
  if (!timeStr) return '--'
  try {
    return new Date(timeStr).toLocaleString('zh-CN', {
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    })
  } catch {
    return timeStr
  }
}
</script>

<style scoped lang="less">
.research-list-page {
  max-width: 1180px;
  margin: 0 auto;
  padding: 28px 24px 40px;
}

.list-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
}

.list-header__main {
  min-width: 0;
}

.list-header__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  font-size: 13px;
  color: #667085;
}

.list-header__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.filter-panel {
  margin-top: 16px;
  padding: 20px 22px;
  border-radius: 18px;
  background: #ffffff;
  border: 1px solid #e8edf5;
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.05);
}

.list-filters {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: stretch;
}

.filter-panel__actions {
  display: inline-flex;
  align-items: center;
  margin-left: auto;
}

.filter-input {
  min-width: 140px;
}

.filter-input--search {
  flex: 1 1 300px;
  min-width: 280px;
}

.filter-input--template {
  min-width: 180px;
}

.filter-input__icon {
  color: rgba(0, 0, 0, 0.28);
}

.filter-panel__switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 0 12px;
  border-radius: 14px;
  background: #f6f8fb;
}

.filter-panel__switch-label {
  font-size: 12px;
  color: #475467;
}

.list-loading {
  display: flex;
  justify-content: center;
  padding: 80px 0;
}

.list-empty {
  padding: 56px 0 32px;
}

.record-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 18px;
}

.record-card {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
  border-radius: 18px;
  padding: 22px 22px 18px;
  border: 1px solid #e8edf5;
  cursor: pointer;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;

  &:hover {
    transform: translateY(-2px);
    border-color: #cfe0ff;
    box-shadow: 0 12px 28px rgba(24, 71, 143, 0.1);
  }

  &__glow {
    position: absolute;
    top: -28px;
    right: -28px;
    width: 120px;
    height: 120px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(44, 125, 255, 0.16) 0%, rgba(44, 125, 255, 0) 68%);
    pointer-events: none;
  }

  &__header {
    position: relative;
    z-index: 1;
  }

  &__title-row {
    min-width: 0;
    margin-bottom: 10px;
  }

  &__title {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
    color: #111827;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  &__status {
    margin-right: 2px;
  }

  &__meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 10px;
  }

  &__time {
    font-size: 12px;
    color: #667085;
    margin-left: auto;
  }

  &__summary-shell {
    position: relative;
    z-index: 1;
    margin: 16px 0 14px;
    padding: 14px 14px 12px;
    border-radius: 12px;
    background: #f7fafd;
    border: 1px solid #eef3f8;
  }

  &__summary {
    font-size: 13px;
    color: #475467;
    line-height: 1.7;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  &__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-top: 12px;
    border-top: 1px solid #edf1f7;
    position: relative;
    z-index: 1;
  }

  &__info {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
  }

  &__version {
    font-size: 12px;
    color: #41516d;
    background: #eef4ff;
    padding: 3px 10px;
    border-radius: 999px;
  }

  &__created {
    font-size: 12px;
    color: #98a2b3;
  }

  &__actions {
    display: flex;
    align-items: center;
    gap: 4px;
  }
}

.list-pagination {
  display: flex;
  justify-content: flex-end;
  margin-top: 24px;
}

@media (max-width: 1080px) {
  .stats-grid,
  .record-list {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 860px) {
  .research-list-page {
    padding: 20px 16px 32px;
  }

  .record-list {
    grid-template-columns: 1fr;
  }

  .list-header {
    flex-direction: column;
  }

  .list-header__actions,
  .filter-panel__actions {
    width: 100%;
    justify-content: flex-start;
  }

  .record-card__footer {
    align-items: flex-start;
    flex-direction: column;
    gap: 10px;
  }

  .record-card__actions {
    width: 100%;
    justify-content: flex-start;
    flex-wrap: wrap;
  }
}

@media (max-width: 640px) {
  .list-header__title {
    font-size: 28px;
  }

  .filter-panel {
    padding: 18px;
  }

  .filter-input,
  .filter-input--search,
  .filter-input--template {
    width: 100%;
    min-width: 100%;
  }
}
</style>
