<template>
  <section id="blog-detail" class="page-section block">
    <div class="max-w-[90rem] mx-auto pt-20 md:pt-32 px-4 md:px-6 pb-12 md:pb-20 relative">
      <!-- 小屏：fixed 返回 -->
      <button
          @click="$router.push('/blog')"
          class="xl:hidden fixed top-20 md:top-24 left-4 md:left-6 z-40 group flex items-center gap-2 rounded-full border border-white/10 bg-[#050505]/80 backdrop-blur-md px-3 py-2 text-art-muted hover:text-white transition-colors"
      >
        <Icon name="arrow-left" :size="16" class="transform group-hover:-translate-x-1 transition-transform" />
        <span class="text-sm font-medium tracking-wide">返回列表</span>
      </button>
      <div class="h-10 mb-6 md:mb-12 xl:hidden" aria-hidden="true"></div>

      <!-- 大屏 loading/error：左侧栏未渲染时的返回 -->
      <button
          v-if="loading || error"
          @click="$router.push('/blog')"
          class="hidden xl:flex fixed top-32 left-[max(1.5rem,calc((100vw-90rem)/2+1.5rem))] z-40 group items-center gap-2 rounded-full border border-white/10 bg-[#050505]/80 backdrop-blur-md px-3 py-2 text-art-muted hover:text-white transition-colors"
      >
        <Icon name="arrow-left" :size="16" class="transform group-hover:-translate-x-1 transition-transform" />
        <span class="text-sm font-medium tracking-wide">返回列表</span>
      </button>

      <!-- Loading state -->
      <div v-if="loading" class="flex justify-center items-center h-64">
        <div class="animate-spin rounded-full h-10 w-10 md:h-12 md:w-12 border-t-2 border-b-2 border-art-accent"></div>
      </div>

      <!-- Error state -->
      <div v-else-if="error" class="text-center text-red-500 py-20">
        <p class="mb-4">{{ error }}</p>
        <button @click="fetchBlogDetail" class="px-4 py-2 bg-art-accent text-white rounded hover:bg-opacity-80 transition-colors">
          重试
        </button>
        <button @click="$router.push('/blog')" class="mt-4 px-4 py-2 border border-white/30 text-white rounded hover:bg-white/5 transition-colors">
          返回文章列表
        </button>
      </div>

      <!-- Blog Layout -->
      <div v-else class="flex flex-col xl:flex-row xl:gap-10 items-start relative">

        <!-- 1. 左侧边栏：元信息 - 仅在大屏显示 -->
        <aside class="hidden xl:block w-64 flex-shrink-0 order-1 sticky top-32 max-h-[calc(100vh-8rem)] overflow-y-auto hide-scrollbar">
          <button
              @click="$router.push('/blog')"
              class="group flex items-center gap-2 rounded-full border border-white/10 bg-white/5 backdrop-blur-md px-3 py-2 mb-6 text-art-muted hover:text-white hover:bg-white/10 transition-colors w-fit"
          >
            <Icon name="arrow-left" :size="16" class="transform group-hover:-translate-x-1 transition-transform" />
            <span class="text-sm font-medium tracking-wide">返回列表</span>
          </button>
          <div class="space-y-6">
            <!-- 专栏跳转卡片 -->
            <div v-if="post.columnId && post.columnName" class="p-5 rounded-xl bg-white/5 border border-white/10 backdrop-blur-md shadow-lg transition-all duration-300 hover:bg-white/10">
              <h3 class="text-xs font-bold text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                <Icon name="book-open" :size="14" class="text-art-accent" />
                所属专栏
              </h3>
              
              <!-- 专栏名称和跳转 -->
              <a
                  @click.prevent="router.push(`/columns/${post.columnId}`)"
                  href="#"
                  class="block p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-white/10 hover:border-art-accent/50 transition-all duration-200 group mb-4"
              >
                <div class="text-sm font-medium text-white group-hover:text-art-accent transition-colors mb-1">
                  {{ post.columnName }}
                </div>
                <div class="text-xs text-art-muted flex items-center gap-1">
                  <Icon name="arrow-right" :size="12" />
                  查看专栏
                </div>
              </a>

              <!-- 专栏文章目录 -->
              <div v-if="columnPosts.length > 0" class="space-y-2">
                <!-- 展开/收起按钮 -->
                <button
                  @click="isColumnExpanded = !isColumnExpanded"
                  class="w-full flex items-center justify-between text-xs text-art-muted hover:text-white transition-colors py-1 px-2 rounded hover:bg-white/5"
                >
                  <span class="font-medium">文章目录</span>
                  <div class="flex items-center gap-1">
                    <span>{{ isColumnExpanded ? '收起' : '展开' }}</span>
                    <Icon 
                      :name="isColumnExpanded ? 'chevron-up' : 'chevron-down'" 
                      :size="14" 
                      class="transition-transform"
                    />
                  </div>
                </button>

                <!-- 文章列表 -->
                <nav class="space-y-0.5 border-t border-white/10 pt-2">
                  <a
                    v-for="columnPost in displayedColumnPosts"
                    :key="columnPost.id"
                    :href="`/blog/${columnPost.id}`"
                    target="_blank"
                    rel="noopener noreferrer"
                    class="block text-xs py-2 px-3 rounded transition-all duration-200 relative group"
                    :class="[
                      columnPost.id === post.id 
                        ? 'text-white pl-4' 
                        : 'text-art-muted hover:text-white hover:bg-white/5'
                    ]"
                  >
                    <div class="line-clamp-2 leading-relaxed">
                      {{ columnPost.title }}
                    </div>
                    <div v-if="columnPost.id === post.id" class="absolute left-0 top-1/2 -translate-y-1/2 w-0.5 h-3 bg-art-accent/40 rounded-full"></div>
                  </a>
                </nav>
              </div>

              <!-- 加载状态 -->
              <div v-else-if="loadingColumnPosts" class="flex items-center justify-center py-4">
                <div class="animate-spin rounded-full h-4 w-4 border-t-2 border-b-2 border-art-accent"></div>
              </div>
            </div>

            <!-- 分类搜索卡片 -->
            <div v-if="post.categoryId && post.categoryName" class="p-5 rounded-xl bg-white/5 border border-white/10 backdrop-blur-md shadow-lg transition-all duration-300 hover:bg-white/10">
              <h3 class="text-xs font-bold text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                <Icon name="folder" :size="14" class="text-art-accent" />
                分类
              </h3>
              <a
                  @click.prevent="handleCategoryClick(post.categoryId)"
                  href="#"
                  class="block p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-white/10 hover:border-art-accent/50 transition-all duration-200 group"
              >
                <div class="text-sm font-medium text-white group-hover:text-art-accent transition-colors mb-1">
                  {{ post.categoryName }}
                </div>
                <div class="text-xs text-art-muted flex items-center gap-1">
                  <Icon name="arrow-right" :size="12" />
                  查看分类
                </div>
              </a>
            </div>

            <!-- 标签搜索卡片 -->
            <div v-if="post.tags && post.tags.length > 0" class="p-5 rounded-xl bg-white/5 border border-white/10 backdrop-blur-md shadow-lg transition-all duration-300 hover:bg-white/10">
              <h3 class="text-xs font-bold text-white uppercase tracking-wider mb-3 flex items-center gap-2">
                <Icon name="tags" :size="14" class="text-art-accent" />
                标签
              </h3>
              <div class="flex flex-wrap gap-2">
                <a
                    v-for="tag in post.tags"
                    :key="tag.id"
                    @click.prevent="handleTagClick(tag.id)"
                    href="#"
                    class="px-2.5 py-1 rounded-md bg-white/5 border border-white/10 hover:bg-art-accent/20 hover:border-art-accent/50 hover:text-art-accent text-xs text-art-muted transition-all duration-200"
                >
                  {{ tag.name }}
                </a>
              </div>
            </div>
          </div>
        </aside>

        <!-- 2. 中间：文章主内容 -->
        <div class="flex-1 min-w-0 max-w-full order-2">
          <!-- 文章头图与信息 -->
          <div class="border-b border-white/5 pb-6 md:pb-8 mb-6 md:mb-10">
            <div class="flex flex-wrap items-center justify-between gap-2 md:gap-3 mb-4 md:mb-6">
              <div class="flex flex-wrap items-center gap-2 md:gap-3">
                <span class="px-2 py-0.5 md:px-3 md:py-1 border border-white/20 rounded-full text-[10px] md:text-xs font-mono text-art-accent uppercase tracking-wider">{{ post.categoryName || '未分类' }}</span>
                <span class="text-xs md:text-sm text-art-muted">{{ post.date }}</span>
              </div>
              <div class="flex items-center gap-2">
                <button
                  type="button"
                  class="flex items-center gap-2 rounded-full border border-white/10 bg-white/5 backdrop-blur-md px-3 py-1.5 md:px-4 md:py-2 text-xs md:text-sm text-art-muted hover:text-white hover:bg-white/10 hover:border-art-accent/30 transition-all duration-200"
                  @click="router.push(`/blog/${postId}/ppt`)"
                >
                  <Icon name="presentation" :size="14" />
                  <span class="font-medium">PPT 预览</span>
                </button>
                <ArticleExportMenu :post="post" :rendered-html="renderedContent" />
              </div>
            </div>
            <h1 class="font-serif text-2xl md:text-5xl lg:text-6xl text-white leading-snug md:leading-tight mb-6 md:mb-8 break-words">{{ post.title }}</h1>
            <AuthorInfo
              :name="post.userName"
              :email="post.userEmail"
              :avatar="post.userAvatar"
              :user-id="post.userId"
              variant="full"
              size="md"
            />
          </div>

          <!-- 文章内容 -->
          <article
              ref="articleRef"
              class="blog-content prose prose-invert min-w-0 max-w-full text-art-muted leading-relaxed prose-base md:prose-lg"
          >
            <div v-html="renderedContent"></div>
          </article>

          <!-- 相关代码片段 -->
          <div v-if="post.snippets && post.snippets.length > 0" class="mt-8 md:mt-12 border-t border-white/10 pt-8 md:pt-10">
            <h3 class="text-base md:text-lg font-bold text-white mb-4 md:mb-6 flex items-center gap-2">
              <Icon name="code-2" :size="18" class="text-art-accent" />
              相关代码
            </h3>
            <div class="grid grid-cols-1 sm:grid-cols-2 gap-3 md:gap-4">
              <button
                v-for="snippet in post.snippets"
                :key="snippet.id"
                type="button"
                class="w-full text-left rounded-xl overflow-hidden bg-[#0d0d0d] border border-white/10 hover:border-art-accent/50 transition-colors group"
                @click="openRelatedSnippet(snippet.id)"
              >
                <div class="flex items-center justify-between px-3 py-2 bg-white/5 border-b border-white/5 gap-2">
                  <div class="flex gap-1.5 shrink-0">
                    <div class="w-2 h-2 rounded-full bg-[#ff5f56]"></div>
                    <div class="w-2 h-2 rounded-full bg-[#ffbd2e]"></div>
                    <div class="w-2 h-2 rounded-full bg-[#27c93f]"></div>
                  </div>
                  <span class="text-[10px] font-mono text-art-accent uppercase truncate">{{ snippet.codeType?.name || snippet.type }}</span>
                </div>
                <div class="p-4">
                  <div class="text-sm font-medium text-white group-hover:text-art-accent transition-colors line-clamp-2">{{ snippet.title }}</div>
                </div>
              </button>
            </div>
          </div>

          <!-- 移动端专属信息补充区 -->
          <div class="xl:hidden mt-8 md:mt-12 border-t border-white/10 pt-6 md:pt-8 space-y-4 md:space-y-6">
            <div v-if="post.tags && post.tags.length > 0">
              <h4 class="text-xs font-bold text-white uppercase tracking-wider mb-2 md:mb-3 flex items-center gap-2">
                <Icon name="tags" :size="14" class="text-art-accent" />
                标签
              </h4>
              <div class="flex flex-wrap gap-2">
                <a
                    v-for="tag in post.tags"
                    :key="tag.id"
                    @click.prevent="handleTagClick(tag.id)"
                    href="#"
                    class="px-2.5 py-1 rounded-full bg-white/5 border border-white/10 text-xs text-art-muted hover:text-white hover:bg-white/10 transition-colors"
                >
                  # {{ tag.name }}
                </a>
              </div>
            </div>

            <div class="flex flex-wrap gap-3 md:gap-4">
              <div v-if="post.columnName" class="flex items-center gap-2 text-xs md:text-sm text-art-muted">
                <Icon name="book-open" :size="14" class="text-art-accent" />
                专栏: <span class="text-white">{{ post.columnName }}</span>
              </div>
              <div v-if="post.categoryName" class="flex items-center gap-2 text-xs md:text-sm text-art-muted">
                <Icon name="folder" :size="14" class="text-art-accent" />
                分类: <span class="text-white">{{ post.categoryName }}</span>
              </div>
            </div>
          </div>

          <!-- 底部推荐阅读 -->
          <div class="mt-8 md:mt-20 border-t border-white/10 pt-8 md:pt-10">
            <h3 class="text-base md:text-lg font-bold text-white mb-4 md:mb-6 flex items-center gap-2">
              <Icon name="sparkles" :size="18" class="text-art-accent" />
              推荐阅读
            </h3>
            <div v-if="loadingRecommendations" class="flex justify-center py-4">
              <div class="animate-spin rounded-full h-6 w-6 border-t-2 border-b-2 border-art-accent"></div>
            </div>
            <div v-else-if="recommendedPosts.length === 0" class="text-sm text-art-muted italic">
              暂无推荐
            </div>
            <div v-else class="grid grid-cols-1 md:grid-cols-2 gap-3 md:gap-4">
              <router-link
                  v-for="recPost in recommendedPosts"
                  :key="recPost.id"
                  :to="`/blog/${recPost.id}`"
                  custom
                  v-slot="{ href }"
              >
                <a
                    :href="href"
                    target="_blank"
                    rel="noopener noreferrer"
                    class="block p-4 md:p-5 rounded-xl bg-white/5 border border-white/10 hover:bg-white/10 hover:border-art-accent/50 transition-all duration-300 group h-full"
                >
                  <div class="text-sm md:text-base font-medium text-white group-hover:text-art-accent transition-colors mb-2 md:mb-3 line-clamp-2">
                    {{ recPost.title }}
                  </div>
                  <div class="flex items-center justify-between gap-2 mt-auto">
                    <AuthorInfo
                      :name="recPost.userName"
                      :email="recPost.userEmail"
                      :avatar="recPost.userAvatar"
                      :user-id="recPost.userId"
                      variant="compact"
                      size="sm"
                    />
                    <span class="text-[10px] md:text-xs text-art-muted shrink-0">{{ recPost.date }}</span>
                  </div>
                </a>
              </router-link>
            </div>
          </div>
        </div>

        <!-- 3. 右侧边栏：目录 (TOC) - 仅在大屏显示 -->
        <aside class="hidden xl:block w-64 flex-shrink-0 order-3 sticky top-32 max-h-[calc(100vh-8rem)] overflow-y-auto hide-scrollbar">
          <div class="p-5 rounded-xl bg-white/5 border border-white/10 backdrop-blur-md shadow-lg transition-all duration-300 hover:bg-white/10">
            <h3 class="text-xs font-bold text-white uppercase tracking-wider mb-4 flex items-center gap-2">
              <Icon name="list" :size="14" class="text-art-accent" />
              目录导航
            </h3>
            <nav class="space-y-1 relative">
              <div
                  class="absolute left-0 w-0.5 bg-art-accent transition-all duration-300 ease-out"
                  :style="activeIndicatorStyle"
                  v-if="toc.length > 0"
              ></div>

              <ul class="space-y-1 border-l border-white/10 ml-[1px]">
                <li v-for="item in toc" :key="item.id">
                  <a
                      @click.prevent="scrollToHeading(item.id)"
                      href="#"
                      class="block text-xs py-1.5 transition-all duration-200 border-l-2 border-transparent pl-4 hover:text-white truncate"
                      :class="[
                      activeId === item.id ? 'text-art-accent font-medium' : 'text-art-muted',
                      item.level > 2 ? 'pl-8' : 'pl-4'
                    ]"
                      :title="item.text"
                  >
                    {{ item.text }}
                  </a>
                </li>
              </ul>
              <div v-if="toc.length === 0" class="text-xs text-art-muted italic pl-4">
                暂无目录
              </div>
            </nav>
          </div>
        </aside>

      </div>
    </div>

    <!-- Mobile TOC Floating Button -->
    <button
        v-if="toc.length > 0 && !loading && !error"
        @click="showMobileToc = true"
        class="xl:hidden fixed bottom-6 right-4 z-50 w-10 h-10 md:w-12 md:h-12 bg-art-accent/90 backdrop-blur text-white rounded-full shadow-lg shadow-art-accent/20 flex items-center justify-center hover:bg-art-accent active:scale-95 transition-all duration-200"
        aria-label="目录"
    >
      <Icon name="list" :size="18" />
    </button>

    <!-- Mobile TOC Drawer -->
    <div v-if="showMobileToc" class="fixed inset-0 z-[100] xl:hidden">
      <div class="absolute inset-0 bg-black/60 backdrop-blur-sm transition-opacity" @click="showMobileToc = false"></div>
      <div class="absolute bottom-0 left-0 right-0 bg-[#1a1a1a] border-t border-white/10 rounded-t-2xl max-h-[70vh] flex flex-col animate-slide-up shadow-2xl">
        <div class="flex items-center justify-between p-4 border-b border-white/10">
          <h3 class="text-sm font-bold text-white flex items-center gap-2">
            <Icon name="list" :size="16" class="text-art-accent" />
            文章目录
          </h3>
          <button @click="showMobileToc = false" class="text-art-muted hover:text-white p-2">
            <Icon name="x" :size="20" />
          </button>
        </div>

        <div class="overflow-y-auto p-4 flex-1">
          <nav class="space-y-1">
            <ul class="space-y-2">
              <li v-for="item in toc" :key="item.id">
                <a
                    @click.prevent="scrollToHeading(item.id); showMobileToc = false"
                    href="#"
                    class="block text-sm py-1 transition-all duration-200 hover:text-white"
                    :class="[
                    activeId === item.id ? 'text-art-accent font-medium' : 'text-art-muted',
                    item.level > 2 ? 'pl-4' : ''
                  ]"
                >
                  {{ item.text }}
                </a>
              </li>
            </ul>
          </nav>
        </div>
      </div>
    </div>

    <SnippetModal
      :is-open="snippetModalOpen"
      :title="activeSnippet.title"
      :code="activeSnippet.code"
      :type="activeSnippet.type"
      :code-type="activeSnippet.codeType"
      :description="activeSnippet.description"
      :posts="activeSnippet.posts"
      @close="closeSnippetModal"
    />

  </section>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, nextTick, onBeforeUnmount, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getCachedSiteTitle } from '../router'
import { fetchPost, getRecommendedPosts, fetchColumnPostTitles, fetchSnippet, Post, Snippet } from '../services/api'
import { useScrollAnimation } from '../composables/useScrollAnimation'
import { renderMarkdown, preloadMarkdownRenderer } from '../utils/markdownRenderer'
import Icon from '../components/Icon.vue'
import AuthorInfo from '../components/AuthorInfo.vue'
import SnippetModal from '../components/SnippetModal.vue'
import ArticleExportMenu from '../components/ArticleExportMenu.vue'
import 'highlight.js/styles/atom-one-dark.css'

const route = useRoute()
const router = useRouter()
const postId = route.params.id as string
const articleRef = ref<HTMLElement | null>(null)

const handleCategoryClick = (categoryId: number) => {
  sessionStorage.setItem('blogFilterCategoryId', categoryId.toString())
  router.push('/blog')
}

const handleTagClick = (tagId: number) => {
  sessionStorage.setItem('blogFilterTagId', tagId.toString())
  router.push('/blog')
}

interface TocItem {
  id: string
  text: string
  level: number
}
const toc = ref<TocItem[]>([])
const activeId = ref<string>('')
const observer = ref<IntersectionObserver | null>(null)
const showMobileToc = ref(false)
const isClickScrolling = ref(false)
let scrollTimeout: number | null = null

const post = ref<Post>({
  id: Number(postId) || 0,
  title: '',
  categoryId: 0,
  date: '',
  excerpt: '',
  content: ''
})

const loading = ref(false)
const error = ref('')
const recommendedPosts = ref<Post[]>([])
const loadingRecommendations = ref(false)

// 专栏文章目录相关状态（仅需 id / title）
const columnPosts = ref<Pick<Post, 'id' | 'title'>[]>([])
const isColumnExpanded = ref(false)
const loadingColumnPosts = ref(false)

const snippetModalOpen = ref(false)
const activeSnippet = ref<Snippet>({ id: 0, title: '', code: '', type: '' })

const openRelatedSnippet = async (snippetId: number) => {
  try {
    const snippet = await fetchSnippet(snippetId)
    activeSnippet.value = snippet
    snippetModalOpen.value = true
  } catch (err) {
    console.error('Failed to load snippet:', err)
  }
}

const closeSnippetModal = () => {
  snippetModalOpen.value = false
}

const { initObserver } = useScrollAnimation()

const renderedContent = ref('')
let renderGeneration = 0

const scheduleArticleEnhancements = () => {
  nextTick(() => {
    initObserver()
    addCopyListeners()
    generateToc()
    initScrollSpy()
  })
}

const renderArticleContent = (content: string) => {
  const generation = ++renderGeneration
  renderedContent.value = ''

  const run = async () => {
    try {
      const html = await renderMarkdown(content)
      if (generation !== renderGeneration) return
      renderedContent.value = html
      scheduleArticleEnhancements()
    } catch (err) {
      console.error('Failed to render markdown:', err)
    }
  }

  if (typeof requestIdleCallback !== 'undefined') {
    requestIdleCallback(() => { void run() }, { timeout: 200 })
  } else {
    setTimeout(() => { void run() }, 0)
  }
}

watch(
  () => post.value.content,
  (content) => {
    if (!content) {
      renderedContent.value = ''
      return
    }
    renderArticleContent(content)
  }
)

const generateToc = () => {
  if (!articleRef.value) return
  const headers = articleRef.value.querySelectorAll('h2, h3')
  const newToc: TocItem[] = []
  headers.forEach((header) => {
    if (header.id && header.textContent) {
      newToc.push({
        id: header.id,
        text: header.textContent,
        level: parseInt(header.tagName.substring(1))
      })
    }
  })
  toc.value = newToc
}

const initScrollSpy = () => {
  if (!articleRef.value) return
  const headers = articleRef.value.querySelectorAll('h2, h3')
  if (headers.length === 0) return
  if (observer.value) observer.value.disconnect()

  observer.value = new IntersectionObserver((entries) => {
    if (isClickScrolling.value) return
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        activeId.value = entry.target.id
      }
    })
  }, {
    rootMargin: '-100px 0px -80% 0px'
  })

  headers.forEach(header => {
    observer.value?.observe(header)
  })
}

const scrollToHeading = (id: string) => {
  const element = document.getElementById(id)
  if (element) {
    isClickScrolling.value = true
    activeId.value = id
    if (scrollTimeout) clearTimeout(scrollTimeout)
    const offset = 100
    const bodyRect = document.body.getBoundingClientRect().top
    const elementRect = element.getBoundingClientRect().top
    const elementPosition = elementRect - bodyRect
    const offsetPosition = elementPosition - offset
    window.scrollTo({
      top: offsetPosition,
      behavior: 'smooth'
    })
    scrollTimeout = window.setTimeout(() => {
      isClickScrolling.value = false
    }, 1000)
  }
}

const activeIndicatorStyle = computed(() => {
  const index = toc.value.findIndex(item => item.id === activeId.value)
  if (index === -1) return { top: '0', opacity: 0 }
  const itemHeight = 28
  return {
    top: `${index * itemHeight}px`,
    height: `${itemHeight}px`,
    opacity: 1
  }
})

// 计算当前文章在专栏文章列表中的索引（根据文章ID查找）
const currentPostIndex = computed(() => {
  if (!post.value.id || columnPosts.value.length === 0) return -1
  // 根据当前文章ID在专栏文章列表中查找索引
  const index = columnPosts.value.findIndex(p => p.id === post.value.id)
  return index
})

// 计算显示的文章列表（默认显示上一个、当前、下一个，展开后显示全部）
const displayedColumnPosts = computed(() => {
  if (columnPosts.value.length === 0) return []
  
  if (isColumnExpanded.value) {
    // 展开状态：显示全部文章
    return columnPosts.value
  }
  
  // 收起状态：根据当前文章ID找到位置，显示上一个、当前、下一个（共3篇）
  const currentIndex = currentPostIndex.value
  
  if (currentIndex === -1) {
    // 如果当前文章不在专栏文章列表中，显示前3篇
    return columnPosts.value.slice(0, Math.min(3, columnPosts.value.length))
  }
  
  // 根据当前文章的位置，计算要显示的范围
  // 目标：显示上一个、当前、下一个（共3篇）
  const total = columnPosts.value.length
  
  // 计算起始索引：尽量显示上一个（如果存在）
  let start = Math.max(0, currentIndex - 1)
  
  // 计算结束索引：尽量显示下一个（如果存在）
  let end = Math.min(total, currentIndex + 2)
  
  // 如果当前文章在开头，确保至少显示当前和下一个
  if (currentIndex === 0 && total > 1) {
    end = Math.min(3, total)
  }
  
  // 如果当前文章在末尾，确保至少显示上一个和当前
  if (currentIndex === total - 1 && total > 1) {
    start = Math.max(0, total - 2)
  }
  
  return columnPosts.value.slice(start, end)
})

const addCopyListeners = () => {
  if (!articleRef.value) return
  const buttons = articleRef.value.querySelectorAll('.copy-btn')
  buttons.forEach(btn => {
    const newBtn = btn.cloneNode(true) as HTMLElement
    btn.parentNode?.replaceChild(newBtn, btn)
    newBtn.addEventListener('click', async () => {
      const container = newBtn.closest('.ios-code-container')
      const codeElement = container?.querySelector('code')
      if (codeElement) {
        try {
          const text = codeElement.innerText
          await navigator.clipboard.writeText(text)
          const originalContent = newBtn.innerHTML
          const checkIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-green-400" style="display: block;"><polyline points="20 6 9 17 4 12"/></svg>`
          newBtn.innerHTML = `<span>${checkIconSvg}</span><span class="text-green-400 text-[10px] md:text-xs font-medium">已复制</span>`
          setTimeout(() => {
            newBtn.innerHTML = originalContent
          }, 2000)
        } catch (err) {
          console.error('Copy failed:', err)
        }
      }
    })
  })
}

const updatePageTitle = (articleTitle: string) => {
  const siteTitle = getCachedSiteTitle()
  document.title = `${siteTitle} | ${articleTitle}`
}

const fetchBlogDetail = async () => {
  loading.value = true
  error.value = ''
  try {
    const postData = await fetchPost(postId)
    if (postData) {
      post.value = postData
      loading.value = false
      if (postData.title) {
        updatePageTitle(postData.title)
      }
      fetchRecommendations()
      if (postData.columnId) {
        fetchColumnPostsList(postData.columnId)
      }
    } else {
      error.value = '未找到该文章'
    }
  } catch (err) {
    console.error('Error fetching blog detail:', err)
    error.value = '获取文章详情失败，请稍后重试'
  } finally {
    loading.value = false
  }
}

const fetchRecommendations = async () => {
  loadingRecommendations.value = true
  try {
    const posts = await getRecommendedPosts(postId, 3)
    recommendedPosts.value = posts
  } catch (err) {
    console.error('Error fetching recommendations:', err)
    recommendedPosts.value = []
  } finally {
    loadingRecommendations.value = false
  }
}

// 加载专栏文章列表
const fetchColumnPostsList = async (columnId?: number) => {
  const id = columnId || post.value.columnId
  if (!id) {
    columnPosts.value = []
    return
  }

  loadingColumnPosts.value = true
  try {
    const posts = await fetchColumnPostTitles(id)
    columnPosts.value = posts || []
  } catch (err) {
    console.error('Error fetching column posts:', err)
    columnPosts.value = []
  } finally {
    loadingColumnPosts.value = false
  }
}

onMounted(() => {
  preloadMarkdownRenderer()
  fetchBlogDetail()
})

onBeforeUnmount(() => {
  if (observer.value) {
    observer.value.disconnect()
  }
  if (scrollTimeout) {
    clearTimeout(scrollTimeout)
  }
})
</script>

<style scoped>
.hide-scrollbar::-webkit-scrollbar {
  display: none;
}
.hide-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

:deep(.prose pre) {
  background-color: transparent !important;
  margin: 0 !important;
  padding: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  border: none !important;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  white-space: pre !important;
}

:deep(.ios-code-container) {
  max-width: 100%;
  min-width: 0;
}

:deep(.code-content-wrapper) {
  min-width: 0;
  max-width: 100%;
}

:deep(.prose table) {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

:deep(.prose code) {
  font-family: 'SF Mono', Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}

:deep(.code-block-wrapper pre code) {
  white-space: pre !important;
  word-wrap: normal !important;
  overflow-wrap: normal !important;
}

:deep(.code-block-wrapper) {
  overflow-x: auto;
  min-width: 0;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
}

:deep(.prose :not(pre) > code) {
  color: #d4b383;
  background-color: rgba(212, 179, 131, 0.1);
  padding: 0.2em 0.4em;
  border-radius: 0.3em;
  font-weight: 500;
  /* 内联代码依然需要换行 */
  word-break: break-word;
}

:deep(.prose h1), :deep(.prose h2), :deep(.prose h3) {
  color: #fff;
  font-family: serif;
  margin-top: 1.5em;
  margin-bottom: 0.6em;
  line-height: 1.3;
  scroll-margin-top: 100px;
}

@media (min-width: 768px) {
  :deep(.prose h1), :deep(.prose h2), :deep(.prose h3) {
    margin-top: 2em;
    margin-bottom: 0.8em;
    scroll-margin-top: 120px;
  }
}

:deep(.prose h2) {
  font-size: 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  padding-bottom: 0.3rem;
}
@media (min-width: 768px) {
  :deep(.prose h2) {
    font-size: 1.8rem;
    padding-bottom: 0.5rem;
  }
}

:deep(.prose h3) {
  font-size: 1.25rem;
  color: rgba(255, 255, 255, 0.9);
}
@media (min-width: 768px) {
  :deep(.prose h3) {
    font-size: 1.4rem;
  }
}

:deep(.prose a) {
  color: #d4b383;
  text-decoration: none;
  border-bottom: 1px dashed rgba(212, 179, 131, 0.5);
  transition: all 0.2s;
  word-break: break-all;
}

:deep(.prose a:hover) {
  color: #fff;
  border-bottom-style: solid;
}

:deep(.prose blockquote) {
  border-left: 3px solid #d4b383;
  background: rgba(255, 255, 255, 0.02);
  padding: 0.8rem 1rem;
  border-radius: 0 0.5rem 0.5rem 0;
  color: rgba(255, 255, 255, 0.7);
  font-style: italic;
}
@media (min-width: 768px) {
  :deep(.prose blockquote) {
    padding: 1rem 1.5rem;
  }
}

:deep(.prose ul li::marker) {
  color: #d4b383;
}

:deep(.prose img) {
  max-width: 100%;
  height: auto;
  border-radius: 0.5rem;
}

:deep(.code-block-wrapper::-webkit-scrollbar) {
  height: 6px;
  background-color: transparent;
}
@media (min-width: 768px) {
  :deep(.code-block-wrapper::-webkit-scrollbar) {
    height: 8px;
  }
}

:deep(.code-block-wrapper::-webkit-scrollbar-thumb) {
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
}

:deep(.code-block-wrapper::-webkit-scrollbar-thumb:hover) {
  background-color: rgba(255, 255, 255, 0.2);
}

:deep(.code-block-wrapper::-webkit-scrollbar-corner) {
  background-color: transparent;
}

:deep(.hljs) {
  background: transparent !important;
}

@keyframes slide-up {
  from {
    transform: translateY(100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
.animate-slide-up {
  animation: slide-up 0.3s ease-out forwards;
}
</style>