<template>
    <view class="nd-page">
        <scroll-view scroll-y class="nd-scroll" style="height: calc(100vh - 100rpx)">
            <view v-if="newsData.is_video && newsData.video_url" class="nd-video">
                <video :src="newsData.video_url" :poster="newsData.image" class="nd-video__player" controls
                    object-fit="cover" />
            </view>
            <view v-else-if="newsData.is_video && newsData.image" class="nd-video">
                <view class="nd-video__cover">
                    <image :src="newsData.image" mode="aspectFill" class="nd-video__img" />
                    <view class="nd-video__play">
                        <view class="nd-video__play-btn">
                            <text class="nd-video__play-icon">▶</text>
                        </view>
                    </view>
                    <view v-if="newsData.duration" class="nd-video__duration">{{ newsData.duration }}</view>
                </view>
            </view>

            <view class="nd-header">
                <text class="nd-header__title">{{ newsData.title }}</text>
                <text v-if="translatedTitle" class="nd-translation-line nd-translation-line--title">{{ translatedTitle }}</text>
                <view class="nd-header__meta">
                    <text class="nd-header__author">{{ newsData.author || '体育小编' }}</text>
                    <text class="nd-header__time">{{ formatTime(newsData.create_time) }}</text>
                    <text class="nd-header__views">{{ newsData.click || 0 }}阅读</text>
                </view>
            </view>

            <view v-if="newsData.abstract || translatedAbstract" class="nd-abstract">
                <text class="nd-abstract__label">摘要</text>
                <text v-if="newsData.abstract" class="nd-abstract__text">{{ newsData.abstract }}</text>
                <text v-if="translatedAbstract" class="nd-abstract__translate">{{ translatedAbstract }}</text>
            </view>

            <view class="nd-content">
                <view v-for="(block, index) in contentBlocks" :key="`content-block-${index}`"
                    class="nd-content__block">
                    <!-- #ifdef H5 -->
                    <div class="nd-content__inner" v-html="block.html"></div>
                    <!-- #endif -->
                    <!-- #ifndef H5 -->
                    <u-parse class="nd-content__parser" :html="block.html" :tag-style="richTextTagStyle"
                        :selectable="true" />
                    <!-- #endif -->
                    <text v-if="block.translated" class="nd-content__translate">{{ block.translated }}</text>
                </view>
            </view>

            <view class="nd-ai-wrap">
                <view class="nd-ai-entry" @tap="goAiAnalysis">
                    <view class="nd-ai-entry__badge">AI</view>
                    <view class="nd-ai-entry__content">
                        <text class="nd-ai-entry__title">获取AI深度解读</text>
                        <text class="nd-ai-entry__desc">智能提炼核心观点与风险分析</text>
                    </view>
                    <view class="nd-ai-entry__arrow">
                        <text>›</text>
                    </view>
                </view>
                <view class="nd-ai-vip">
                    <text v-if="isVipUser" class="nd-ai-vip__tag nd-ai-vip__tag--vip">VIP</text>
                    <text v-if="isVipUser" class="nd-ai-vip__text">尊贵的{{ vipLevelName }}，到期时间{{ vipExpireDate }}</text>
                    <text v-if="!isVipUser" class="nd-ai-vip__tag">免费</text>
                    <text v-if="!isVipUser" class="nd-ai-vip__text">{{ AI_DAILY_FREE_TEXT }}，今日剩余{{ freeRemain }}次</text>
                </view>
            </view>

            <view class="nd-comments">
                <view class="nd-comments__header">
                    <text class="nd-comments__title">评论 ({{ commentTotal }})</text>
                </view>
                <view v-if="commentList.length === 0" class="nd-comments__empty">
                    <text>暂无评论，快来发表你的看法吧</text>
                </view>
                <view v-for="c in commentList" :key="c.id" class="nd-comment">
                    <image :src="c.avatar || '/static/images/avatar.png'" class="nd-comment__avatar" mode="aspectFill" />
                    <view class="nd-comment__body">
                        <text class="nd-comment__name">{{ c.nickname }}</text>
                        <text class="nd-comment__text">{{ c.content }}</text>
                        <text class="nd-comment__time">{{ formatTime(c.create_time) }}</text>
                        <view v-if="c.reply_list && c.reply_list.length" class="nd-comment__replies">
                            <view v-for="r in c.reply_list" :key="r.id" class="nd-comment__reply">
                                <text class="nd-comment__reply-name">{{ r.nickname }}</text>
                                <text v-if="r.reply_nickname" class="nd-comment__reply-to">回复 {{ r.reply_nickname }}</text>
                                <text class="nd-comment__reply-text">{{ r.content }}</text>
                            </view>
                        </view>
                    </view>
                </view>
                <view v-if="commentList.length > 0 && commentList.length < commentTotal" class="nd-comments__more"
                    @tap="loadMoreComments">
                    <text>加载更多评论</text>
                </view>
            </view>

            <view v-if="relatedList.length > 0" class="nd-related">
                <text class="nd-related__title">相关推荐</text>
                <navigator v-for="r in relatedList" :key="r.id" :url="`/pages/news_detail/news_detail?id=${r.id}`"
                    class="nd-related__item">
                    <view class="nd-related__info">
                        <text class="nd-related__name">{{ r.title }}</text>
                        <text class="nd-related__meta">{{ r.click || 0 }}阅读</text>
                    </view>
                    <image v-if="r.image" :src="r.image" class="nd-related__img" mode="aspectFill" />
                </navigator>
            </view>

            <view style="height: 120rpx" />
        </scroll-view>

        <view class="nd-bar">
            <view class="nd-bar__input" @tap="showCommentInput">
                <view class="nd-bar__input-icon">
                    <u-icon name="edit-pen" :size="28" color="#185dff" />
                </view>
                <view class="nd-bar__input-text">
                    <text class="nd-bar__placeholder">写下你的评论...</text>
                    <text class="nd-bar__hint">{{ commentTotal ? `${commentTotal}条讨论` : '抢先参与讨论' }}</text>
                </view>
            </view>
            <view class="nd-bar__actions">
                <view class="nd-bar__item" :class="{ 'nd-bar__item--active': voteStatus === 1 }" @tap="handleLike">
                    <view class="nd-bar__icon">
                        <u-icon name="thumb-up" :size="34" :color="voteStatus === 1 ? '#185dff' : '#5f6673'" />
                    </view>
                    <text :class="{ 'nd-bar__active': voteStatus === 1 }">{{ formatActionCount(newsData.like_count || 0) }}</text>
                </view>
                <view class="nd-bar__item" :class="{ 'nd-bar__item--active': newsData.collect }" @tap="handleCollect">
                    <view class="nd-bar__icon">
                        <u-icon :name="newsData.collect ? 'star-fill' : 'star'" :size="34"
                            :color="newsData.collect ? '#f0ad4e' : '#5f6673'" />
                    </view>
                    <text :class="{ 'nd-bar__active': newsData.collect }">{{ newsData.collect ? '已藏' : '收藏' }}</text>
                </view>
                <view class="nd-bar__item" @tap="handleShare">
                    <view class="nd-bar__icon">
                        <u-icon name="share" :size="34" color="#5f6673" />
                    </view>
                    <text>分享</text>
                </view>
            </view>
        </view>

        <u-popup v-model="commentPopup" mode="bottom">
            <view class="nd-cpop">
                <view class="nd-cpop__header">
                    <text class="nd-cpop__title">发表评论</text>
                    <text class="nd-cpop__close" @tap="commentPopup = false">×</text>
                </view>
                <textarea v-model="commentContent" class="nd-cpop__textarea" placeholder="说说你的看法..."
                    :maxlength="500" :auto-height="true" :focus="commentPopup" />
                <view class="nd-cpop__footer">
                    <text class="nd-cpop__count">{{ commentContent.length }}/500</text>
                    <view class="nd-cpop__btn" :class="{ 'nd-cpop__btn--disabled': !commentContent.trim() }"
                        @tap="submitComment">
                        <text>发布</text>
                    </view>
                </view>
            </view>
        </u-popup>

        <share-popup v-if="showSharePopup" v-model:show="showSharePopup" page-type="news" :page-id="newsId"
            :path="`/pages/news_detail/news_detail?id=${newsId}`" :title="newsData.title || ''" />
        <GlobalPopup />
    </view>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue'
import SharePopup from '@/components/share-popup/share-popup.vue'
import GlobalPopup from '@/components/global-popup/global-popup.vue'
import { onLoad } from '@dcloudio/uni-app'
import { getArticleDetail, addCollect, cancelCollect, getCommentList, addComment, articleVote } from '@/api/news'
import request from '@/utils/request'
import { useUserStore } from '@/stores/user'
import { AI_DAILY_FREE_TEXT, getAiFreeRemain } from '@/config/ai'

const userStore = useUserStore()
const vipInfo = computed(() => userStore.userInfo?.vip_info || {})
const isVipUser = computed(() => !!vipInfo.value.is_vip)
const vipLevelName = computed(() => vipInfo.value.vip_level_name || '会员')
const vipExpireDate = computed(() => vipInfo.value.vip_expire_time || '')
const freeRemain = computed(() => getAiFreeRemain(vipInfo.value))

const newsData = ref<any>({})
const relatedList = ref<any[]>([])
const voteStatus = ref(0)
let newsId = ''

const commentList = ref<any[]>([])
const commentTotal = ref(0)
const commentPage = ref(1)
const commentPopup = ref(false)
const commentContent = ref('')
const showSharePopup = ref(false)

const extractTranslatedContent = (data: any) => {
    if (!data) return ''
    if (data.translated_content) return data.translated_content
    const ext = data.ext
    if (!ext) return ''
    if (typeof ext === 'string') {
        try {
            const parsed = JSON.parse(ext)
            return parsed?.translated_content || ''
        } catch (e) {
            return ''
        }
    }
    return ext.translated_content || ''
}

const translatedContent = computed(() => extractTranslatedContent(newsData.value))

const translatedParts = computed(() => {
    const raw = translatedContent.value || ''
    const lines = raw
        .replace(/\r\n/g, '\n')
        .split('\n')
        .map((line) => line.trim())
        .filter(Boolean)

    const parts = {
        title: '',
        abstract: '',
        body: [] as string[],
    }

    let mode: 'title' | 'abstract' | 'body' = 'body'
    for (const line of lines) {
        const titleMatch = line.match(/^标题[:：]\s*(.*)$/)
        const abstractMatch = line.match(/^摘要[:：]\s*(.*)$/)
        const bodyMatch = line.match(/^正文[:：]\s*(.*)$/)

        if (titleMatch) {
            parts.title = titleMatch[1]?.trim() || ''
            mode = 'title'
            continue
        }

        if (abstractMatch) {
            parts.abstract = abstractMatch[1]?.trim() || ''
            mode = 'abstract'
            continue
        }

        if (bodyMatch) {
            mode = 'body'
            const bodyText = bodyMatch[1]?.trim()
            if (bodyText) {
                parts.body.push(bodyText)
            }
            continue
        }

        if (mode === 'body') {
            parts.body.push(line)
        } else if (mode === 'title' && !parts.title) {
            parts.title = line
        } else if (mode === 'abstract' && !parts.abstract) {
            parts.abstract = line
        }
    }

    return parts
})

const translatedTitle = computed(() => translatedParts.value.title)
const translatedAbstract = computed(() => translatedParts.value.abstract)
const translatedBodyLines = computed(() => translatedParts.value.body)

const richTextTagStyle = {
    p: 'margin:0;line-height:1.52;font-size:22rpx;color:#333;word-break:break-word;',
    div: 'margin:0;line-height:1.52;font-size:22rpx;color:#333;word-break:break-word;',
    li: 'margin:0;line-height:1.52;font-size:22rpx;color:#333;word-break:break-word;',
    h1: 'margin:8rpx 0;font-size:34rpx;font-weight:700;line-height:1.35;color:#1f2937;',
    h2: 'margin:8rpx 0;font-size:30rpx;font-weight:700;line-height:1.38;color:#1f2937;',
    h3: 'margin:8rpx 0;font-size:28rpx;font-weight:700;line-height:1.4;color:#1f2937;',
    blockquote: 'margin:8rpx 0;padding:8rpx 16rpx;border-left:6rpx solid #d6def2;background:#f7f9fc;color:#4b5563;',
    img: 'max-width:100%;height:auto;display:block;margin:10px 0;',
}

const normalizeImageAttrs = (attrs: string) => {
    let normalized = String(attrs || '').replace(/\/\s*$/, '').trim()
    if (!/\breferrerpolicy\s*=/i.test(normalized)) {
        normalized = `${normalized} referrerpolicy="no-referrer"`.trim()
    }

    const imageStyle = 'max-width:100%;height:auto;display:block;margin:10px 0;'
    const styleMatch = normalized.match(/(^|\s)style=(["'])(.*?)\2/i)
    if (styleMatch) {
        const mergedStyle = `${styleMatch[3].replace(/;?\s*$/, ';')}${imageStyle}`
        return normalized.replace(styleMatch[0], `${styleMatch[1]}style=${styleMatch[2]}${mergedStyle}${styleMatch[2]}`)
    }

    return `${normalized} style="${imageStyle}"`.trim()
}

const normalizeHtml = (html: string) => {
    if (!html) return ''
    return String(html).replace(/<img\b([^>]*)>/gi, (_match, attrs = '') => `<img ${normalizeImageAttrs(attrs)}>`)
}

const stripHtmlText = (html: string) => {
    if (!html) return ''
    return String(html)
        .replace(/<img[^>]*>/gi, ' ')
        .replace(/<br\s*\/?>/gi, '\n')
        .replace(/<\/p>/gi, '\n')
        .replace(/<\/li>/gi, '\n')
        .replace(/<\/div>/gi, '\n')
        .replace(/<\/blockquote>/gi, '\n')
        .replace(/<\/figcaption>/gi, '\n')
        .replace(/<\/section>/gi, '\n')
        .replace(/<\/article>/gi, '\n')
        .replace(/<[^>]+>/g, ' ')
        .replace(/&nbsp;/g, ' ')
        .replace(/&amp;/g, '&')
        .replace(/&quot;/g, '"')
        .replace(/&#x27;|&#39;/gi, "'")
        .replace(/&#x2f;/gi, '/')
        .replace(/&#x60;/gi, '`')
        .replace(/&#x3d;/gi, '=')
        .replace(/&#39;/g, "'")
        .replace(/\s+/g, ' ')
        .trim()
}

const splitContentLines = (text: string) => {
    const normalized = String(text || '')
        .replace(/\r\n/g, '\n')
        .replace(/\r/g, '\n')
        .trim()
    if (!normalized) return []

    const manualLines = normalized
        .split('\n')
        .map((line) => line.replace(/\s+/g, ' ').trim())
        .filter(Boolean)

    if (manualLines.length > 1) return manualLines

    const sentenceLines = normalized
        .replace(/\s+/g, ' ')
        .match(/[^。！？.!?]+[。！？.!?]?/g)
        ?.map((line) => line.trim())
        .filter(Boolean)

    return sentenceLines?.length ? sentenceLines : [normalized]
}

const escapeHtml = (text: string) => {
    return String(text || '')
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
}

const flattenHtmlBlocks = (block: string): string[] => {
    const htmlBlock = /<[^>]+>/.test(block) ? block : `<p>${block}</p>`
    const trimmedBlock = htmlBlock.trim()
    const listTagMatch = trimmedBlock.match(/^<(ul|ol)\b/i)
    if (listTagMatch) {
        const listTag = listTagMatch[1].toLowerCase()
        const liMatches = Array.from(trimmedBlock.matchAll(/<li\b[^>]*>[\s\S]*?<\/li>/gi)).map((match) => match[0])
        if (liMatches.length) {
            return liMatches.map((liHtml) => `<${listTag}>${liHtml}</${listTag}>`)
        }
    }

    const childMatches = Array.from(
        trimmedBlock.matchAll(/<(p|div|blockquote|li|figcaption|section|article)\b[^>]*>[\s\S]*?<\/\1>/gi)
    )
        .map((match) => match[0])
        .filter((child) => child.trim() !== trimmedBlock)

    if (childMatches.length > 1) {
        return childMatches.flatMap((child) => flattenHtmlBlocks(child))
    }

    return [htmlBlock]
}

const parseContentBlocks = (html: string) => {
    const content = String(html || '').trim()
    if (!content) return []

    const paragraphMatches = Array.from(
        content.matchAll(/<(p|h[1-6]|blockquote|ul|ol|figure|div|figcaption|section|article)\b[^>]*>[\s\S]*?<\/\1>/gi)
    ).map((match) => match[0])
    const blocks = paragraphMatches.length ? paragraphMatches : content
        .split(/\n{2,}/)
        .map((item) => item.trim())
        .filter(Boolean)

    return blocks.reduce((result: { html: string; text: string; isText: boolean; isListItem: boolean; listTag: string }[], block) => {
        flattenHtmlBlocks(block).forEach((flatBlock) => {
            const text = stripHtmlText(flatBlock)
            const hasImage = /<img\b/i.test(flatBlock)
            const isHeading = /^<h[1-6]\b/i.test(flatBlock.trim())
            const isListItem = /^<(ul|ol)\b/i.test(flatBlock.trim()) || /^<li\b/i.test(flatBlock.trim())
            const listTag = flatBlock.trim().match(/^<(ul|ol)\b/i)?.[1]?.toLowerCase() || 'ul'

            if (text && !hasImage && !isHeading) {
                result.push({
                    html: normalizeHtml(flatBlock),
                    text,
                    isText: true,
                    isListItem,
                    listTag
                })
                return
            }

            result.push({
                html: normalizeHtml(flatBlock),
                text,
                isText: false,
                isListItem: false,
                listTag: ''
            })
        })
        return result
    }, [])
}

const contentBlocks = computed(() => {
    const paragraphBlocks = parseContentBlocks(newsData.value?.content || '')
    const sentenceBlocks = paragraphBlocks.reduce((result: { html: string; isText: boolean }[], block) => {
        if (!block.isText) {
            result.push({
                html: block.html,
                isText: false
            })
            return result
        }

        const lines = splitContentLines(block.text)
        if (lines.length <= 1) {
            result.push({
                html: block.html,
                isText: true
            })
            return result
        }

        lines.forEach((line) => {
            result.push({
                html: block.isListItem
                    ? `<${block.listTag} style="margin:0;padding-left:1.2em;"><li>${escapeHtml(line)}</li></${block.listTag}>`
                    : `<p>${escapeHtml(line)}</p>`,
                isText: true
            })
        })
        return result
    }, [])

    const sentenceTranslations: string[] = []
    translatedBodyLines.value
        .map((line) => line.trim())
        .filter(Boolean)
        .forEach((line) => {
        sentenceTranslations.push(...splitContentLines(line))
    })

    let translationIndex = 0
    return sentenceBlocks.map((block) => {
        if (!block.isText) {
            return {
                html: block.html,
                translated: ''
            }
        }

        const translated = sentenceTranslations[translationIndex] || ''
        translationIndex += 1

        return {
            html: block.html,
            translated
        }
    })
})

const getData = async (id: string) => {
    newsData.value = await getArticleDetail({ id })
    voteStatus.value = newsData.value.vote_status || 0
    fetchRelated()
    fetchComments(true)
}

const fetchRelated = async () => {
    try {
        const cid = newsData.value?.cid
        if (!cid) return
        const res = await request.get({
            url: '/article/lists',
            data: { cid, page_no: 1, page_size: 4 }
        }, { withToken: false })
        relatedList.value = (res?.lists || []).filter((r: any) => r.id !== newsData.value.id).slice(0, 3)
    } catch (e) {
        // ignore
    }
}

const fetchComments = async (reset = false) => {
    if (reset) {
        commentPage.value = 1
        commentList.value = []
    }
    try {
        const res = await getCommentList({
            article_id: newsId,
            page_no: commentPage.value,
            page_size: 15
        })
        commentTotal.value = res.count || 0
        if (reset) {
            commentList.value = res.lists || []
        } else {
            commentList.value = [...commentList.value, ...(res.lists || [])]
        }
    } catch (e) {
        // ignore
    }
}

const loadMoreComments = () => {
    commentPage.value++
    fetchComments()
}

const showCommentInput = () => {
    if (!userStore.isLogin) {
        uni.showModal({
            title: '提示',
            content: '登录后才能评论，是否前往登录？',
            confirmText: '去登录',
            cancelText: '取消',
            success: (res) => {
                if (res.confirm) {
                    uni.navigateTo({ url: '/pages/login/login' })
                }
            }
        })
        return
    }
    commentContent.value = ''
    commentPopup.value = true
}

const submitComment = async () => {
    const content = commentContent.value.trim()
    if (!content) return
    try {
        await addComment({ article_id: newsId, content })
        uni.showToast({ title: '评论成功', icon: 'success' })
        commentPopup.value = false
        commentContent.value = ''
        fetchComments(true)
    } catch (e: any) {
        if (!/token|登录/.test(String(e))) {
            uni.$u.toast(e || '评论失败，请重试')
        }
    }
}

const handleLike = async () => {
    try {
        const res = await articleVote({ article_id: Number(newsId), vote_type: 1 })
        voteStatus.value = res.action === 'cancel' ? 0 : 1
        newsData.value.like_count = res.like_count
        newsData.value.dislike_count = res.dislike_count
    } catch (e) {
        // ignore
    }
}

const handleCollect = async () => {
    try {
        if (newsData.value.collect) {
            await cancelCollect({ id: Number(newsId) })
            newsData.value.collect = 0
            uni.showToast({ title: '已取消收藏', icon: 'none' })
        } else {
            await addCollect({ id: Number(newsId) })
            newsData.value.collect = 1
            uni.showToast({ title: '收藏成功', icon: 'success' })
        }
    } catch (e) {
        // ignore
    }
}

const goAiAnalysis = () => {
    if (!newsId) return
    const title = encodeURIComponent(newsData.value.title || '')
    uni.navigateTo({ url: `/pages/ai_analysis/ai_analysis?type=article&id=${newsId}&title=${title}` })
}

const handleShare = () => {
    showSharePopup.value = true
}

const formatActionCount = (value: number | string) => {
    const count = Number(value || 0)
    if (!Number.isFinite(count) || count <= 0) return '点赞'
    if (count >= 10000) return `${(count / 10000).toFixed(count >= 100000 ? 0 : 1)}万`
    if (count > 999) return '999+'
    return String(count)
}

const formatTime = (t: string) => {
    if (!t) return ''
    const d = new Date(t.replace(/-/g, '/'))
    if (isNaN(d.getTime())) return t
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`
}

onLoad((options: any) => {
    newsId = options.id
    getData(newsId)
})
</script>

<style lang="scss" scoped>
.nd-page {
    min-height: 100vh;
    background: #fff;
}

.nd-scroll {
    background: #fff;
}

.nd-video {
    width: 100%;

    &__player {
        width: 100%;
        height: 420rpx;
    }

    &__cover {
        position: relative;
        width: 100%;
        height: 420rpx;
    }

    &__img {
        width: 100%;
        height: 100%;
    }

    &__play {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    &__play-btn {
        width: 100rpx;
        height: 100rpx;
        border-radius: 50%;
        background: rgba(0, 0, 0, 0.5);
        display: flex;
        align-items: center;
        justify-content: center;
    }

    &__play-icon {
        color: #fff;
        font-size: 44rpx;
        margin-left: 8rpx;
    }

    &__duration {
        position: absolute;
        right: 20rpx;
        bottom: 20rpx;
        background: rgba(0, 0, 0, 0.6);
        color: #fff;
        font-size: 22rpx;
        padding: 4rpx 14rpx;
        border-radius: 6rpx;
    }
}

.nd-header {
    padding: 24rpx 32rpx 10rpx;

    &__title {
        font-size: 34rpx;
        font-weight: 700;
        color: #1a1a1a;
        line-height: 1.36;
        display: block;
        word-break: break-word;
    }

    &__meta {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 18rpx;
        margin-top: 12rpx;
        white-space: nowrap;
    }

    &__author {
        font-size: 22rpx;
        color: #185dff;
        font-weight: 500;
    }

    &__time {
        font-size: 22rpx;
        color: #999;
    }

    &__views {
        font-size: 22rpx;
        color: #bbb;
    }
}

.nd-abstract {
    margin: 0 32rpx 14rpx;
    padding: 16rpx 20rpx;
    background: #f8f8f8;
    border-radius: 12rpx;
    border-left: 6rpx solid #185dff;

    &__label {
        font-size: 22rpx;
        color: #185dff;
        font-weight: 600;
        display: block;
        margin-bottom: 6rpx;
    }

    &__text {
        display: block;
        font-size: 24rpx;
        color: #666;
        line-height: 1.55;
    }

    &__translate {
        display: block;
        margin-top: 4rpx;
        padding-left: 0;
        font-size: 26rpx;
        color: #3f4a5a;
        line-height: 1.58;
        word-break: break-word;
    }
}

.nd-content {
    padding: 0 32rpx 32rpx;
    font-size: 22rpx;
    color: #333;
    line-height: 1.52;
    word-break: break-word;

    &__block {
        margin-bottom: 8rpx;

        &:last-child {
            margin-bottom: 0;
        }
    }

    &__translate {
        display: block;
        margin-top: 0;
        padding-left: 0;
        font-size: 26rpx;
        color: #3f4a5a;
        line-height: 1.54;
        white-space: pre-wrap;
        word-break: break-word;
    }
}

.nd-content__inner {
    font-size: 22rpx;
    color: #333;
    line-height: 1.52;
    word-break: break-word;
}

.nd-content__inner :deep(p) {
    margin: 0;
    line-height: 1.52;
}

.nd-content__inner :deep(ul),
.nd-content__inner :deep(ol) {
    margin: 0;
    padding-left: 1.2em;
}

.nd-content__inner :deep(li) {
    margin: 0;
    line-height: 1.52;
}

.nd-content__inner :deep(img) {
    margin: 10rpx 0;
}

.nd-translation-line {
    display: block;
    margin: 6rpx 32rpx 0;
    padding-left: 0;
    font-size: 26rpx;
    color: #3f4a5a;
    line-height: 1.56;
    white-space: pre-wrap;
    word-break: break-word;
}

.nd-translation-line--title {
    margin-top: 6rpx;
    font-size: 26rpx;
    color: #1f2937;
    font-weight: 600;
}

.nd-ai-wrap {
    display: flex;
    flex-direction: column;
    gap: 16rpx;
    margin-bottom: 8rpx;
}

.nd-ai-entry {
    display: flex;
    flex-direction: row;
    align-items: center;
    margin: 0 32rpx 0;
    padding: 28rpx;
    background: linear-gradient(135deg, #667eea, #764ba2);
    border-radius: 16rpx;
    gap: 20rpx;

    &__badge {
        width: 72rpx;
        height: 72rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        background: rgba(255, 255, 255, 0.25);
        border-radius: 16rpx;
        font-size: 28rpx;
        font-weight: 900;
        color: #fff;
        letter-spacing: 2rpx;
        flex-shrink: 0;
    }

    &__content {
        flex: 1;
    }

    &__title {
        font-size: 30rpx;
        font-weight: 600;
        color: #fff;
        display: block;
    }

    &__desc {
        font-size: 22rpx;
        color: rgba(255, 255, 255, 0.75);
        display: block;
        margin-top: 8rpx;
    }

    &__arrow {
        width: 48rpx;
        height: 48rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        background: rgba(255, 255, 255, 0.2);
        border-radius: 50%;
        flex-shrink: 0;

        text {
            font-size: 36rpx;
            color: #fff;
            font-weight: bold;
        }
    }
}

.nd-ai-vip {
    display: flex;
    align-items: center;
    gap: 10rpx;
    margin: 16rpx 32rpx 20rpx;
    padding: 12rpx 20rpx;
    background: #f0f4ff;
    border-radius: 10rpx;

    &__tag {
        font-size: 20rpx;
        font-weight: 900;
        color: #fff;
        background: linear-gradient(135deg, #6366f1, #8b5cf6);
        padding: 4rpx 14rpx;
        border-radius: 8rpx;
        letter-spacing: 2rpx;

        &--vip {
            background: linear-gradient(135deg, #f59e0b, #d97706);
        }
    }

    &__text {
        font-size: 22rpx;
        color: #666;
    }
}

.nd-related {
    padding: 24rpx 32rpx;
    border-top: 16rpx solid #f5f5f5;

    &__title {
        font-size: 30rpx;
        font-weight: 600;
        color: #333;
        display: block;
        margin-bottom: 20rpx;
    }

    &__item {
        display: flex;
        flex-direction: row;
        gap: 20rpx;
        padding: 20rpx 0;
        border-bottom: 1rpx solid #f5f5f5;

        &:last-child {
            border-bottom: none;
        }
    }

    &__info {
        flex: 1;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }

    &__name {
        font-size: 28rpx;
        color: #333;
        line-height: 1.5;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        word-break: break-word;
    }

    &__meta {
        font-size: 22rpx;
        color: #bbb;
        margin-top: 8rpx;
    }

    &__img {
        width: 200rpx;
        height: 140rpx;
        border-radius: 8rpx;
        flex-shrink: 0;
    }
}

.nd-comments {
    padding: 24rpx 32rpx;
    border-top: 16rpx solid #f5f5f5;

    &__header {
        margin-bottom: 20rpx;
    }

    &__title {
        font-size: 30rpx;
        font-weight: 600;
        color: #333;
    }

    &__empty {
        padding: 60rpx 0;
        text-align: center;
        font-size: 26rpx;
        color: #bbb;
    }

    &__more {
        padding: 24rpx 0;
        text-align: center;
        font-size: 26rpx;
        color: #185dff;
    }
}

.nd-comment {
    display: flex;
    flex-direction: row;
    padding: 20rpx 0;
    border-bottom: 1rpx solid #f5f5f5;

    &__avatar {
        width: 64rpx;
        height: 64rpx;
        border-radius: 50%;
        flex-shrink: 0;
        margin-right: 16rpx;
    }

    &__body {
        flex: 1;
        min-width: 0;
    }

    &__name {
        font-size: 24rpx;
        color: #999;
        display: block;
        margin-bottom: 8rpx;
    }

    &__text {
        font-size: 28rpx;
        color: #333;
        line-height: 1.6;
        display: block;
        word-break: break-word;
    }

    &__time {
        font-size: 22rpx;
        color: #bbb;
        display: block;
        margin-top: 8rpx;
    }

    &__replies {
        margin-top: 16rpx;
        padding: 16rpx;
        background: #f8f8f8;
        border-radius: 8rpx;
    }

    &__reply {
        margin-bottom: 12rpx;
        font-size: 26rpx;
        line-height: 1.6;

        &:last-child {
            margin-bottom: 0;
        }
    }

    &__reply-name {
        color: #185dff;
        font-weight: 500;
    }

    &__reply-to {
        color: #999;
        margin: 0 8rpx;
    }

    &__reply-text {
        color: #333;
    }
}

.nd-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    background: #fff;
    border-top: 1rpx solid #eef0f4;
    box-shadow: 0 -8rpx 28rpx rgba(31, 41, 55, 0.08);
    padding: 14rpx 20rpx;
    padding-bottom: calc(env(safe-area-inset-bottom) + 14rpx);
    z-index: 10;
    gap: 14rpx;

    &__input {
        flex: 1;
        min-width: 0;
        height: 76rpx;
        display: flex;
        flex-direction: row;
        align-items: center;
        background: #f7f9fc;
        border: 1rpx solid #edf1f7;
        border-radius: 40rpx;
        padding: 0 18rpx;
        gap: 12rpx;
        box-sizing: border-box;
    }

    &__input-icon {
        width: 44rpx;
        height: 44rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #eaf1ff;
        border-radius: 50%;
        flex-shrink: 0;
    }

    &__input-text {
        flex: 1;
        min-width: 0;
        display: flex;
        flex-direction: column;
        justify-content: center;
        gap: 2rpx;
    }

    &__placeholder {
        font-size: 25rpx;
        color: #1f2937;
        line-height: 1.15;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    &__hint {
        font-size: 19rpx;
        color: #98a1b2;
        line-height: 1.15;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    &__actions {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 8rpx;
        flex-shrink: 0;
    }

    &__item {
        width: 68rpx;
        height: 76rpx;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 4rpx;
        font-size: 18rpx;
        color: #5f6673;
        line-height: 1;
        border-radius: 20rpx;
        flex-shrink: 0;
    }

    &__item--active {
        background: #f2f6ff;
    }

    &__icon {
        width: 38rpx;
        height: 38rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
    }

    &__active {
        color: #185dff;
        font-weight: 600;
    }
}

.nd-cpop {
    padding: 32rpx;
    padding-bottom: calc(env(safe-area-inset-bottom) + 32rpx);

    &__header {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 24rpx;
    }

    &__title {
        font-size: 32rpx;
        font-weight: 600;
        color: #333;
    }

    &__close {
        font-size: 44rpx;
        color: #999;
        padding: 0 8rpx;
    }

    &__textarea {
        width: 100%;
        min-height: 200rpx;
        max-height: 400rpx;
        font-size: 28rpx;
        color: #333;
        line-height: 1.7;
        padding: 20rpx;
        background: #f8f8f8;
        border-radius: 12rpx;
        box-sizing: border-box;
    }

    &__footer {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        margin-top: 20rpx;
    }

    &__count {
        font-size: 24rpx;
        color: #bbb;
    }

    &__btn {
        background: #185dff;
        color: #fff;
        font-size: 26rpx;
        padding: 12rpx 40rpx;
        border-radius: 32rpx;

        &--disabled {
            opacity: 0.5;
        }
    }
}
</style>
