<script setup lang="ts">
/**
 * 公告详情
 *
 * 展示公告富文本正文，右侧提供最新公告快捷入口
 */
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
  ArrowLeft,
  Calendar,
  Clock,
  InfoFilled,
  View
} from '@element-plus/icons-vue'
import AppHeader from '@/components/layout/AppHeader.vue'
import AppFooter from '@/components/layout/AppFooter.vue'
import EmptyState from '@/components/common/EmptyState.vue'
import { getNoticeDetailApi, getNoticePageApi } from '@/api/notice'
import type { NoticeItem } from '@/types/notice'
import { formatDateTime } from '@/utils/date'
import { getNoticeTypeMeta, formatNoticeRange } from '@/utils/notice'

const route = useRoute()
const router = useRouter()

const noticeId = computed(() => Number(route.params.id))
const loading = ref(true)
const notice = ref<NoticeItem | null>(null)
const latestLoading = ref(true)
const latestNotices = ref<NoticeItem[]>([])

async function loadNotice() {
  const id = noticeId.value
  if (!Number.isFinite(id) || id <= 0) {
    router.replace('/404')
    return
  }
  loading.value = true
  notice.value = null
  try {
    notice.value = await getNoticeDetailApi(id)
    document.title = `${notice.value.title} - 零食商城`
  } catch {
    notice.value = null
  } finally {
    loading.value = false
  }
}

async function loadLatest() {
  latestLoading.value = true
  try {
    const res = await getNoticePageApi({ current: 1, size: 6 })
    latestNotices.value = (res.records || [])
      .filter(item => item.id !== noticeId.value)
      .slice(0, 5)
  } catch {
    latestNotices.value = []
  } finally {
    latestLoading.value = false
  }
}

function goDetail(item: NoticeItem) {
  if (item.id === noticeId.value) return
  router.push(`/notice/${item.id}`)
}

watch(() => route.params.id, () => {
  loadNotice()
  loadLatest()
})

onMounted(() => {
  loadNotice()
  loadLatest()
})
</script>

<template>
  <div class="notice-detail-page">
    <AppHeader />

    <main class="detail-main">
      <div class="container">
        <div class="back-bar">
          <button type="button" class="back-btn" @click="router.push('/notice')">
            <el-icon :size="15"><ArrowLeft /></el-icon>
            返回公告中心
          </button>
        </div>

        <div v-if="loading" class="article-skeleton">
          <div class="skeleton-line skeleton-title" />
          <div class="skeleton-line skeleton-short" />
          <div class="skeleton-line" />
          <div class="skeleton-block" />
        </div>

        <div v-else-if="!notice" class="error-box">
          <el-icon :size="52" class="error-icon"><InfoFilled /></el-icon>
          <h2>公告不存在或已下线</h2>
          <p>这条公告可能已经被删除或已过期</p>
          <el-button type="primary" round @click="router.push('/notice')">
            返回公告中心
          </el-button>
        </div>

        <template v-else>
          <div class="detail-layout">
            <article class="article-card">
              <div class="article-head">
                <div class="badge-row">
                  <span
                    class="type-badge"
                    :class="getNoticeTypeMeta(notice.type).className"
                  >
                    {{ getNoticeTypeMeta(notice.type).label }}
                  </span>
                  <span v-if="notice.isTop === 1" class="top-badge">置顶</span>
                </div>
                <h1 class="article-title">{{ notice.title }}</h1>
                <div class="article-meta">
                  <span class="meta-item">
                    <el-icon :size="14"><Clock /></el-icon>
                    发布时间：{{ formatDateTime(notice.createTime) }}
                  </span>
                  <span class="meta-divider">|</span>
                  <span class="meta-item">
                    <el-icon :size="14"><View /></el-icon>
                    浏览：{{ notice.viewCount ?? 0 }}
                  </span>
                  <span class="meta-divider">|</span>
                  <span class="meta-item">
                    <el-icon :size="14"><Calendar /></el-icon>
                    有效期：{{ formatNoticeRange(notice.startTime, notice.endTime) }}
                  </span>
                </div>
              </div>
              <div class="article-content" v-html="notice.content" />
            </article>

            <aside class="latest-panel">
              <h2 class="panel-title">最新公告</h2>
              <el-skeleton v-if="latestLoading" :rows="4" animated />
              <template v-else>
                <div v-if="latestNotices.length" class="latest-list">
                  <div
                    v-for="item in latestNotices"
                    :key="item.id"
                    class="latest-item"
                    @click="goDetail(item)"
                  >
                    <span
                      class="latest-badge"
                      :class="getNoticeTypeMeta(item.type).className"
                    >
                      {{ getNoticeTypeMeta(item.type).label }}
                    </span>
                    <div class="latest-info">
                      <span class="latest-title">{{ item.title }}</span>
                      <span class="latest-date">
                        {{ formatDateTime(item.createTime, 'MM-DD HH:mm') }}
                      </span>
                    </div>
                  </div>
                </div>
                <EmptyState v-else description="暂无更多公告" />
              </template>
            </aside>
          </div>
        </template>
      </div>
    </main>

    <AppFooter />
  </div>
</template>

<style lang="scss" scoped>
.notice-detail-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: $bg-page;
}

.detail-main {
  flex: 1;
  padding: 20px 0 48px;
}

.container {
  max-width: $container-max;
  margin: 0 auto;
  padding: 0 24px;
}

// ==================== 返回栏 ====================
.back-bar {
  margin-bottom: 20px;
}

.back-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 16px;
  border: 2px solid $color-border;
  border-radius: $radius-full;
  background: $bg-surface;
  color: $color-text-regular;
  font-size: $font-size-sm;
  font-weight: 600;
  box-shadow: 0 2px 0 0 $color-border-dark;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, transform 0.2s, box-shadow 0.2s;

  &:hover {
    color: $color-primary;
    border-color: $color-primary;
    transform: translateY(-1px);
  }
}

// ==================== 骨架屏 ====================
.article-skeleton {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 32px;
  background: $bg-surface;
  border: 2px solid $color-border;
  border-radius: $radius-lg;
  box-shadow: $clay-shadow-sm;
}

.skeleton-line {
  height: 20px;
  width: 100%;
  border-radius: 6px;
  background: $bg-hover;
}

.skeleton-title {
  height: 34px;
  width: 60%;
}

.skeleton-short {
  width: 35%;
}

.skeleton-block {
  height: 260px;
  border-radius: $radius-md;
  background: $bg-hover;
}

// ==================== 错误态 ====================
.error-box {
  text-align: center;
  padding: 80px 20px;
  background: $bg-surface;
  border: 2px solid $color-border;
  border-radius: $radius-lg;
  box-shadow: $clay-shadow-sm;

  .error-icon {
    color: $color-primary;
    margin-bottom: 16px;
  }

  h2 {
    margin: 0 0 8px;
    color: $color-text-primary;
  }

  p {
    margin: 0 0 24px;
    font-size: $font-size-sm;
    color: $color-text-secondary;
  }
}

// ==================== 双栏布局 ====================
.detail-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 24px;
  align-items: start;
}

.article-card {
  background: $bg-surface;
  border: 2px solid $color-border;
  border-radius: $radius-lg;
  box-shadow: $clay-shadow-sm;
  overflow: hidden;
}

.article-head {
  padding: 32px 36px 24px;
  border-bottom: 2px solid $color-border;
}

.badge-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}

.type-badge,
.top-badge {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 3px 12px;
  border-radius: $radius-full;
  font-size: $font-size-xs;
  font-weight: 700;
  line-height: 1.5;
}

.type-badge {
  &.type-normal {
    background: $bg-hover;
    color: $color-text-secondary;
  }

  &.type-important {
    background: #FEF3C7;
    color: $color-warning;
  }

  &.type-event {
    background: $color-primary-light;
    color: $color-primary;
  }
}

.top-badge {
  background: linear-gradient(135deg, $color-primary, $color-cta);
  color: #fff;
}

.article-title {
  margin: 0 0 18px;
  font-size: $font-size-display;
  font-weight: 700;
  color: $color-text-primary;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.article-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  font-size: $font-size-xs;
  color: $color-text-secondary;
}

.meta-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.meta-divider {
  color: $color-border-dark;
}

// ==================== 富文本正文 ====================
.article-content {
  padding: 32px 36px;
  font-size: $font-size-md;
  line-height: 1.8;
  color: $color-text-primary;
  overflow-wrap: break-word;

  :deep(p) {
    margin: 0 0 14px;
  }

  :deep(h1),
  :deep(h2),
  :deep(h3),
  :deep(h4),
  :deep(h5),
  :deep(h6) {
    margin: 24px 0 12px;
    color: $color-text-primary;
    line-height: 1.4;
  }

  :deep(img) {
    max-width: 100%;
    height: auto;
    border-radius: $radius-sm;
  }

  :deep(a) {
    color: $color-primary;
  }

  :deep(ul),
  :deep(ol) {
    margin: 0 0 14px;
    padding-left: 24px;
  }

  :deep(li) {
    margin-bottom: 6px;
  }

  :deep(blockquote) {
    margin: 0 0 14px;
    padding: 10px 16px;
    border-left: 4px solid $color-primary;
    border-radius: 8px;
    background: $color-primary-light;
    color: $color-text-regular;
  }

  :deep(pre) {
    margin: 0 0 14px;
    padding: 14px 16px;
    border-radius: 10px;
    background: #2B2422;
    color: #F5E9E3;
    overflow-x: auto;
    font-size: $font-size-sm;
    line-height: 1.6;
  }

  :deep(code) {
    padding: 2px 6px;
    border-radius: 4px;
    background: $bg-hover;
    font-size: 13px;
  }

  :deep(pre code) {
    padding: 0;
    background: transparent;
  }

  :deep(table) {
    width: 100%;
    margin: 0 0 14px;
    border-collapse: collapse;
  }

  :deep(th),
  :deep(td) {
    padding: 8px 12px;
    border: 1px solid $color-border;
    text-align: left;
  }

  :deep(hr) {
    margin: 24px 0;
    border: none;
    border-top: 2px solid $color-border;
  }
}

// ==================== 最新公告 ====================
.latest-panel {
  padding: 22px;
  background: $bg-surface;
  border: 2px solid $color-border;
  border-radius: $radius-lg;
  box-shadow: $clay-shadow-sm;
}

.panel-title {
  margin: 0 0 16px;
  font-family: 'Fredoka', 'PingFang SC', sans-serif;
  font-size: $font-size-lg;
  font-weight: 700;
  color: $color-text-primary;
}

.latest-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.latest-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px;
  border: 2px solid transparent;
  border-radius: $radius-sm;
  cursor: pointer;
  transition: border-color 0.2s, background-color 0.2s;

  &:hover {
    border-color: $color-border;
    background: $color-primary-light;
  }
}

.latest-badge {
  flex-shrink: 0;
  min-width: 40px;
  padding: 2px 8px;
  border-radius: $radius-full;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.5;
  text-align: center;

  &.type-normal {
    background: $bg-hover;
    color: $color-text-secondary;
  }

  &.type-important {
    background: #FEF3C7;
    color: $color-warning;
  }

  &.type-event {
    background: $color-primary-light;
    color: $color-primary;
  }
}

.latest-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.latest-title {
  font-size: $font-size-sm;
  font-weight: 600;
  color: $color-text-primary;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.latest-date {
  font-size: $font-size-xs;
  color: $color-text-secondary;
}

// ==================== 响应式 ====================
@media (max-width: 980px) {
  .detail-layout {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .container {
    padding: 0 16px;
  }

  .article-head {
    padding: 24px 20px 20px;
  }

  .article-content {
    padding: 24px 20px;
  }

  .article-title {
    font-size: $font-size-xxl;
  }

  .article-meta {
    gap: 8px;
  }
}
</style>
