<script setup lang="ts">
import { computed, shallowRef } from 'vue'
import { formatDate, formatDateCompact, formatDateTime } from '../../lib/format'
import type { ClsNewsDocument, ClsNewsItem, ClsSectorImpact, Sentiment } from '../../types'

interface Props {
  news: ClsNewsDocument | null
  loading: boolean
  selectedDate: string
}

const props = defineProps<Props>()

const emit = defineEmits<{
  refresh: []
}>()

const keyword = shallowRef('')
const selectedSource = shallowRef('全部来源')

const sourceOptions = computed(() => {
  const sources = new Set((props.news?.items ?? []).map((item) => item.source))
  return ['全部来源', ...sources]
})

const filteredItems = computed<ClsNewsItem[]>(() => {
  const items = props.news?.items ?? []
  const normalizedKeyword = keyword.value.trim().toLowerCase()

  return items.filter((item) => {
    const matchSource = selectedSource.value === '全部来源' || item.source === selectedSource.value
    const matchKeyword =
      !normalizedKeyword ||
      item.title.toLowerCase().includes(normalizedKeyword) ||
      item.summary.toLowerCase().includes(normalizedKeyword)
    return matchSource && matchKeyword
  })
})

const visibleImpacts = computed<ClsSectorImpact[]>(() => {
  const impacts = props.news?.sector_impacts ?? []
  if (!filteredItems.value.length) {
    return impacts
  }
  const visibleSectorSet = new Set(filteredItems.value.flatMap((item) => item.sectors))
  const matched = impacts.filter((impact) => visibleSectorSet.has(impact.sector))
  return matched.length ? matched : impacts
})

const watchList = computed(() => props.news?.summary.watch_list ?? [])

function sentimentClass(sentiment: Sentiment) {
  return {
    'sentiment--positive': sentiment === '看多',
    'sentiment--negative': sentiment === '看空',
    'sentiment--neutral': sentiment === '中性',
  }
}

function impactCardClass(impact: ClsSectorImpact) {
  return {
    'impact-item--positive': impact.sentiment === '看多',
    'impact-item--negative': impact.sentiment === '看空',
    'impact-item--neutral': impact.sentiment === '中性',
  }
}
</script>

<template>
  <section class="panel">
    <div class="panel-head">
      <div class="panel-title-group">
        <p class="eyebrow">CLS Live Monitor</p>
        <h2 class="panel-title">{{ formatDate(selectedDate) }} 财联社 7x24</h2>
        <p class="panel-subtitle">左侧日期会同步联动热点概览和资讯列表，仅展示所选日期当日资讯。</p>
      </div>
      <button class="refresh-button" type="button" @click="emit('refresh')">
        {{ loading ? '刷新中...' : '刷新当日资讯' }}
      </button>
    </div>

    <div v-if="news" class="panel-grid">
      <article class="summary-card">
        <div class="summary-top">
          <div class="summary-heading">
            <p class="summary-label">{{ news.window_label }}</p>
            <h3 class="summary-title">热点概览</h3>
          </div>
          <div class="summary-meta">
            <span class="summary-meta-item">{{ formatDateCompact(news.date) }}</span>
            <span class="summary-meta-item">最近更新 {{ formatDateTime(news.updated_at) }}</span>
            <span class="summary-meta-item">3 分钟更新</span>
          </div>
        </div>

        <div class="summary-copy-group">
          <p class="summary-copy">{{ news.summary.overview }}</p>
          <p class="summary-copy summary-copy--secondary">{{ news.summary.hot_topics }}</p>
        </div>

        <div class="watch-strip">
          <span class="watch-label">关键方向</span>
          <div class="watch-tags">
            <span v-for="sector in watchList" :key="sector" class="sector-tag">{{ sector }}</span>
          </div>
        </div>

        <div class="impact-list">
          <article
            v-for="impact in visibleImpacts"
            :key="impact.sector"
            class="impact-item"
            :class="impactCardClass(impact)"
          >
            <div class="impact-head">
              <div class="impact-copy">
                <strong class="impact-sector">{{ impact.sector }}</strong>
                <p class="impact-reason">{{ impact.reason }}</p>
              </div>
              <span class="sentiment" :class="sentimentClass(impact.sentiment)">{{ impact.sentiment }}</span>
            </div>

            <ul class="impact-links">
              <li v-for="title in impact.related_titles" :key="title" class="impact-link-item">
                {{ title }}
              </li>
            </ul>
          </article>

          <div v-if="visibleImpacts.length === 0" class="impact-empty">
            当前筛选条件下没有可展示的热点概览。
          </div>
        </div>
      </article>

      <div class="feed-card">
        <div class="feed-head">
          <div class="feed-head-copy">
            <span class="feed-title">资讯列表</span>
            <span class="feed-caption">展示 {{ formatDate(selectedDate) }} 全天财联社推送，可直接滚轮浏览</span>
          </div>
          <span class="feed-count">{{ filteredItems.length }} / {{ news.items.length }} 条</span>
        </div>

        <div class="filter-row">
          <input
            v-model="keyword"
            class="filter-input"
            type="text"
            placeholder="按资讯标题或摘要筛选"
          />
          <select v-model="selectedSource" class="filter-select">
            <option v-for="source in sourceOptions" :key="source" :value="source">
              {{ source }}
            </option>
          </select>
        </div>

        <div class="feed-list">
          <article v-for="item in filteredItems" :key="item.id" class="feed-item">
            <div class="item-meta">
              <span>{{ item.source }}</span>
              <span>{{ formatDateTime(item.published_at) }}</span>
              <span class="sentiment" :class="sentimentClass(item.sentiment)">{{ item.sentiment }}</span>
            </div>
            <h3 class="item-title">{{ item.title }}</h3>
            <p class="item-summary">{{ item.summary }}</p>
            <div class="item-foot">
              <div class="sector-row">
                <span v-for="sector in item.sectors" :key="sector" class="sector-tag">{{ sector }}</span>
              </div>
              <a class="link-button" :href="item.reference_url" target="_blank" rel="noreferrer">
                参考链接
              </a>
            </div>
          </article>

          <div v-if="filteredItems.length === 0" class="feed-empty">
            当前筛选条件下没有匹配的资讯。
          </div>
        </div>
      </div>
    </div>

    <div v-else class="empty-state">
      <p>{{ loading ? '资讯加载中...' : '当前日期暂无资讯数据。' }}</p>
    </div>
  </section>
</template>

<style scoped>
.panel {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: 12px;
  min-height: 0;
  padding: 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xl);
  background: var(--bg-panel);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.panel-title-group {
  display: grid;
  gap: 4px;
}

.eyebrow {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.panel-title {
  margin: 0;
  font-family: "Palatino Linotype", "STSong", "Songti SC", serif;
  font-size: 24px;
  color: var(--ink-strong);
}

.panel-subtitle {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-soft);
}

.refresh-button {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: 999px;
  color: white;
  background: linear-gradient(135deg, #9f6531, #7e4c26);
  box-shadow: 0 10px 30px rgba(126, 76, 38, 0.22);
}

.panel-grid {
  display: grid;
  grid-template-columns: minmax(320px, 0.78fr) minmax(0, 1.22fr);
  gap: 12px;
  min-height: 0;
}

.summary-card,
.feed-card {
  min-height: 0;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-panel-strong);
}

.summary-card {
  display: grid;
  grid-template-rows: auto auto auto 1fr;
  gap: 10px;
  padding: 14px;
  overflow: hidden;
}

.summary-top {
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border-radius: 20px;
  background:
    linear-gradient(145deg, rgba(159, 101, 49, 0.12), rgba(255, 255, 255, 0.84)),
    rgba(255, 249, 242, 0.92);
}

.summary-heading {
  display: grid;
  gap: 4px;
}

.summary-label {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.summary-title {
  margin: 0;
  font-size: 18px;
  color: var(--ink-strong);
}

.summary-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.summary-meta-item {
  padding: 6px 10px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.74);
}

.summary-copy-group {
  display: grid;
  gap: 8px;
}

.summary-copy {
  margin: 0;
  font-size: 13px;
  line-height: 1.58;
  color: var(--ink-main);
}

.summary-copy--secondary {
  color: var(--ink-soft);
}

.watch-strip {
  display: grid;
  gap: 8px;
}

.watch-label {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.watch-tags,
.sector-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.sector-tag {
  padding: 6px 10px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--accent);
  background: var(--accent-soft);
}

.impact-list {
  display: grid;
  align-content: start;
  gap: 8px;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

.impact-item {
  display: grid;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--line-soft);
  border-left-width: 4px;
  border-radius: 18px;
  background: rgba(255, 248, 239, 0.88);
}

.impact-item--positive {
  border-left-color: rgba(27, 122, 94, 0.64);
}

.impact-item--negative {
  border-left-color: rgba(154, 75, 69, 0.64);
}

.impact-item--neutral {
  border-left-color: rgba(103, 100, 93, 0.46);
}

.impact-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.impact-copy {
  display: grid;
  gap: 6px;
}

.impact-sector {
  font-size: 15px;
  color: var(--ink-strong);
}

.impact-reason {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-main);
}

.impact-links {
  display: grid;
  gap: 6px;
  margin: 0;
  padding-left: 18px;
  color: var(--ink-soft);
}

.impact-link-item {
  font-size: 12px;
  line-height: 1.58;
}

.impact-empty,
.feed-empty {
  padding: 18px 16px;
  border: 1px dashed var(--line-strong);
  border-radius: 18px;
  color: var(--ink-soft);
  background: rgba(255, 252, 248, 0.72);
}

.feed-card {
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: 10px;
  padding: 14px;
}

.feed-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.feed-head-copy {
  display: grid;
  gap: 4px;
}

.feed-title {
  font-size: 16px;
  color: var(--ink-strong);
}

.feed-caption {
  font-size: 12px;
  color: var(--ink-soft);
}

.feed-count {
  flex: 0 0 auto;
  padding: 8px 12px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-main);
  background: rgba(0, 0, 0, 0.05);
}

.filter-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 180px;
  gap: 10px;
}

.filter-input,
.filter-select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  color: var(--ink-main);
  background: rgba(255, 255, 255, 0.82);
  outline: none;
}

.filter-input:focus,
.filter-select:focus {
  border-color: rgba(143, 90, 45, 0.36);
}

.feed-list {
  display: grid;
  gap: 8px;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

.feed-item {
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: rgba(255, 248, 239, 0.84);
}

.item-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 12px;
  color: var(--ink-soft);
}

.sentiment {
  flex: 0 0 auto;
  padding: 3px 9px;
  border-radius: 999px;
}

.sentiment--positive {
  color: var(--positive);
  background: rgba(27, 122, 94, 0.12);
}

.sentiment--negative {
  color: var(--negative);
  background: rgba(154, 75, 69, 0.12);
}

.sentiment--neutral {
  color: var(--neutral);
  background: rgba(103, 100, 93, 0.12);
}

.item-title {
  margin: 0;
  font-size: 15px;
  line-height: 1.38;
  color: var(--ink-strong);
}

.item-summary {
  margin: 0;
  font-size: 12px;
  line-height: 1.56;
  color: var(--ink-main);
}

.item-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.link-button {
  flex: 0 0 auto;
  padding: 8px 12px;
  border-radius: 999px;
  color: var(--ink-strong);
  background: rgba(0, 0, 0, 0.05);
}

.empty-state {
  display: grid;
  place-items: center;
  min-height: 240px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  color: var(--ink-soft);
}

@media (max-width: 1180px) {
  .panel-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 820px) {
  .panel-head,
  .feed-head,
  .impact-head {
    flex-direction: column;
    align-items: stretch;
  }

  .filter-row {
    grid-template-columns: 1fr;
  }

  .refresh-button,
  .feed-count,
  .sentiment {
    align-self: flex-start;
  }
}
</style>
