// 文章详情页
const { useState, useEffect, useCallback, useRef, Component } = React;

// 最外层错误边界：任何 JS 报错都不会导致整页白屏
class ArticleErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, errorInfo: '' };
  }
  static getDerivedStateFromError(error) {
    return { hasError: true, errorInfo: error?.message || '' };
  }
  componentDidCatch(error, errorInfo) {
    console.error('[ArticleDetail] 渲染错误:', error, errorInfo);
  }
  render() {
    if (this.state.hasError) {
      return this.props.fallback || (
        <div className="page-container">
          <AppHeader title="文章详情" showBack={true} onBack={this.props.onBack || (() => {})} />
          <div style={{ padding: '40px 20px', textAlign: 'center' }}>
            <div style={{ fontSize: '40px', marginBottom: 16 }}>⚠️</div>
            <div style={{ fontSize: '16px', color: '#333', marginBottom: 8, fontWeight: 600 }}>页面加载异常</div>
            <div style={{ fontSize: '13px', color: '#999', marginBottom: 20 }}>
              {this.state.errorInfo || '文章内容暂时无法显示'}
            </div>
            <button
              onClick={() => {
                this.setState({ hasError: false, errorInfo: '' });
                if (this.props.onRetry) this.props.onRetry();
              }}
              style={{
                padding: '10px 24px',
                background: '#ff6b35',
                color: '#fff',
                border: 'none',
                borderRadius: 20,
                fontSize: '14px',
              }}
            >重新加载</button>
          </div>
        </div>
      );
    }
    return this.props.children;
  }
}

// 模块级错误边界：单个模块报错不影响整页
class SafeSection extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError() {
    return { hasError: true };
  }
  componentDidCatch(error) {
    console.error(`[SafeSection:${this.props.label || 'unknown'}] 渲染错误:`, error);
  }
  render() {
    if (this.state.hasError) {
      return this.props.fallback || null;
    }
    return this.props.children;
  }
}

function ArticleDetailPage() {
  const { navigate, goBack, showToast, api, currentUser, pageParams, currentPage, requireLogin } = useApp();
  const [article, setArticle] = useState(null);
  const [loading, setLoading] = useState(true);
  const [showPasswordModal, setShowPasswordModal] = useState(false);
  const [passwordInput, setPasswordInput] = useState('');
  const [showRewardModal, setShowRewardModal] = useState(false);
  const [rewardAmount, setRewardAmount] = useState(5);
  const [rewardMessage, setRewardMessage] = useState('');
  const [showPayModal, setShowPayModal] = useState(false);
  const [comments, setComments] = useState([]);
  const [commentTotal, setCommentTotal] = useState(0);
  const [commentText, setCommentText] = useState('');
  const [replyTo, setReplyTo] = useState(null); // {id, nickname}
  const [rewards, setRewards] = useState([]);
  const [showRewardsList, setShowRewardsList] = useState(false);
  const commentInputRef = useRef(null);

  const articleId = pageParams?.articleDetail?.id || pageParams?.['article-detail']?.id || window.__articleId || 1;

  const loadArticle = useCallback(async () => {
    setLoading(true);
    try {
      const res = await api.get(`/articles/${articleId}`);
      if (res.success) {
        const raw = res.data || {};
        const safeArticle = {
          id: raw.id || 0,
          title: raw.title || '',
          content: raw.content || '',
          user_id: raw.user_id || 0,
          nickname: raw.nickname || '匿名用户',
          avatar: raw.avatar || '',
          cover_image: raw.cover_image || '',
          category_id: raw.category_id || null,
          category_name: raw.category_name || '',
          visibility: raw.visibility || 'public',
          price: raw.price || 0,
          is_paid: !!raw.is_paid,
          preview_only: !!raw.preview_only,
          reward_enabled: raw.reward_enabled !== false,
          likes_count: raw.likes_count || 0,
          comments_count: raw.comments_count || 0,
          rewards_count: raw.rewards_count || 0,
          reward_amount: raw.reward_amount || 0,
          views_count: raw.views_count || 0,
          created_at: raw.created_at || new Date().toISOString(),
          is_liked: !!raw.is_liked,
          ...raw,
        };
        setArticle(safeArticle);
        if (res.code === 'NEED_PASSWORD') {
          setShowPasswordModal(true);
        }
      } else {
        showToast(res.message || '文章不存在');
        setTimeout(goBack, 1500);
      }
    } catch(e) {
      showToast('加载失败');
    } finally {
      setLoading(false);
    }
  }, [articleId, api, showToast, goBack]);

  const loadComments = useCallback(async () => {
    try {
      const res = await api.get(`/articles/${articleId}/comments`);
      if (res.success) {
        setComments(res.data.main_comments || []);
        setCommentTotal(res.data.total || 0);
      }
    } catch(e) {}
  }, [articleId, api]);

  const loadRewards = useCallback(async () => {
    try {
      const res = await api.get(`/articles/${articleId}/rewards`);
      if (res.success) setRewards(res.data || []);
    } catch(e) {}
  }, [articleId, api]);

  useEffect(() => {
    loadArticle();
    loadComments();
    loadRewards();
  }, [loadArticle, loadComments, loadRewards]);

  // Update SEO when article data is ready
  useEffect(() => {
    if (!article || !window.SEO) return;
    const title = article.seo_title || article.title || '';
    const description = article.seo_description || SEO.truncate(SEO.stripHtml(article.content || ''), 100);
    const keywords = article.seo_keywords || (Array.isArray(article.tags) ? article.tags.join(',') : (article.category_name || ''));
    SEO.setSEO({
      title: title,
      description: description,
      keywords: keywords,
      ogImage: article.cover_image || article.seo_image || '',
      ogType: 'article',
    });
    // Cleanup: reset when leaving
    return () => {
      if (window.SEO) SEO.applyPageSEO('article-list');
    };
  }, [article]);

  const handleUnlock = async () => {
    if (!passwordInput.trim()) {
      showToast('请输入密码');
      return;
    }
    try {
      const res = await api.post(`/articles/${articleId}/unlock`, { password: passwordInput });
      if (res.success) {
        setShowPasswordModal(false);
        setPasswordInput('');
        loadArticle();
        showToast('解锁成功');
      } else {
        showToast(res.message || '密码错误');
      }
    } catch(e) {
      showToast('解锁失败');
    }
  };

  const handleLike = () => {
    if (!article) return;
    if (!requireLogin(() => handleLike())) return;
    api.post(`/articles/${articleId}/like`).then(res => {
      if (res.success) {
        setArticle(prev => ({
          ...prev,
          is_liked: res.data.liked,
          likes_count: (prev.likes_count || 0) + (res.data.liked ? 1 : -1)
        }));
      }
    }).catch(() => {});
  };

  const handlePay = () => {
    if (!requireLogin(() => handlePay())) return;
    api.post(`/articles/${articleId}/pay`).then(res => {
      if (res.success) {
        setShowPayModal(false);
        showToast('购买成功');
        loadArticle();
      } else {
        showToast(res.message || '购买失败');
      }
    }).catch(() => { showToast('购买失败'); });
  };

  const handleReward = () => {
    if (!rewardAmount || rewardAmount <= 0) {
      showToast('请输入打赏金额');
      return;
    }
    if (!requireLogin(() => handleReward())) return;
    api.post(`/articles/${articleId}/reward`, {
      amount: rewardAmount,
      message: rewardMessage
    }).then(res => {
      if (res.success) {
        setShowRewardModal(false);
        setRewardMessage('');
        showToast('打赏成功，感谢支持！');
        loadArticle();
        loadRewards();
      } else {
        showToast(res.message || '打赏失败');
      }
    }).catch(() => { showToast('打赏失败'); });
  };

  const submitComment = () => {
    if (!commentText.trim()) {
      showToast('请输入评论内容');
      return;
    }
    if (!requireLogin(() => submitComment())) return;
    const body = { content: commentText.trim() };
    if (replyTo) {
      body.parent_id = replyTo.parent_id || replyTo.id;
      body.reply_to_user_id = replyTo.user_id || 0;
      body.reply_to_nickname = replyTo.nickname || '';
    }
    api.post(`/articles/${articleId}/comments`, body).then(res => {
      if (res.success) {
        setCommentText('');
        setReplyTo(null);
        showToast('评论成功');
        loadComments();
        setArticle(prev => ({
          ...prev,
          comments_count: (prev.comments_count || 0) + 1
        }));
      } else {
        showToast(res.message || '评论失败');
      }
    }).catch(() => { showToast('评论失败'); });
  };

  const formatTime = (t) => {
    if (!t) return '';
    try {
      const d = new Date(String(t).replace(' ', 'T'));
      if (isNaN(d.getTime())) return String(t).substring(0, 10);
      const now = new Date();
      const diff = (now - d) / 1000;
      if (diff < 0) return String(t).substring(5, 16);
      if (diff < 60) return '刚刚';
      if (diff < 3600) return Math.floor(diff / 60) + '分钟前';
      if (diff < 86400) return Math.floor(diff / 3600) + '小时前';
      return String(t).substring(5, 16);
    } catch(e) {
      return '';
    }
  };

  if (loading) {
    return (
      <div className="page-container">
        <AppHeader title="文章详情" showBack={true} onBack={goBack} />
        <div className="loading-state">加载中...</div>
      </div>
    );
  }

  if (!article) {
    return (
      <div className="page-container">
        <AppHeader title="文章详情" showBack={true} onBack={goBack} />
        <div className="empty-state">文章不存在</div>
      </div>
    );
  }

  return (
    <ArticleErrorBoundary onBack={goBack} onRetry={loadArticle}>
      <div className="page-container">
        <AppHeader
          title="文章详情"
          showBack={true}
          onBack={goBack}
          rightContent={
            <div className="icon-btn" onClick={() => {
              showToast('分享链接已复制');
            }}>↗</div>
          }
        />

        <SafeSection
          label="article-header"
          fallback={
            <div className="article-detail">
              <div className="article-detail-header">
                <h1 className="article-detail-title">{article?.title || ''}</h1>
              </div>
            </div>
          }
        >
          <div className="article-detail">
            {/* 文章标题区 */}
            <div className="article-detail-header">
              <h1 className="article-detail-title">{article?.title || ''}</h1>
              <div className="article-detail-meta">
                <div className="article-author-info">
                  {article?.avatar && <img src={article.avatar} alt="" />}
                  <div>
                    <div className="author-name">{article?.nickname || '匿名用户'}</div>
                    <div className="author-stats">
                      <span>{formatTime(article?.created_at)}</span>
                      <span>·</span>
                      <span>{(article?.views_count || 0)} 阅读</span>
                      {article?.category_name && (
                        <>
                          <span>·</span>
                          <span className="cat-inline">{article.category_name}</span>
                        </>
                      )}
                    </div>
                  </div>
                </div>
              </div>
            </div>

            {/* 封面图 */}
            {article?.cover_image && (
              <div className="article-detail-cover">
                <img src={article.cover_image} alt="" />
              </div>
            )}

            {/* 正文（XSS 过滤后渲染） */}
            <div className="article-detail-content" dangerouslySetInnerHTML={{ __html: sanitizeHtml(article?.content || '') }} />

            {/* 付费解锁提示 */}
            <SafeSection label="pay-wall">
              {article?.preview_only && (
                <div className="pay-wall">
                  <div className="pay-wall-icon">🔒</div>
                  <div className="pay-wall-title">本文为付费文章</div>
                  <div className="pay-wall-desc">支付 ¥{article?.price || 0} 即可阅读全文</div>
                  <button className="pay-wall-btn" onClick={() => setShowPayModal(true)}>
                    立即解锁 · ¥{article?.price || 0}
                  </button>
                </div>
              )}
            </SafeSection>

            {/* 标签 */}
            <SafeSection label="article-tags">
              {((article?.price || 0) > 0 || !article?.reward_enabled) && (article?.user_id || 0) !== 1 && (
                <div className="article-tags">
                  {(article?.price || 0) > 0 && article?.is_paid && (
                    <span className="tag tag-success">✓ 已购买</span>
                  )}
                  {article?.visibility === 'password' && (
                    <span className="tag">🔒 密码文章</span>
                  )}
                </div>
              )}
            </SafeSection>

            {/* 打赏榜 */}
            <SafeSection label="reward-section">
              {article?.reward_enabled && rewards.length > 0 && (
                <div className="reward-section">
                  <div className="reward-header" onClick={() => setShowRewardsList(true)}>
                    <span>🏆 打赏榜</span>
                    <span className="reward-count">{(article?.rewards_count || 0)} 人打赏</span>
                  </div>
                  <div className="reward-avatars">
                    {(rewards || []).slice(0, 8).map((r, i) => (
                      <div key={r.id || i} className="reward-avatar-item" title={`${r.nickname || ''} ¥${r.amount || 0}`}>
                        <img src={r.avatar || ''} alt="" />
                        <span className="reward-amount">¥{r.amount || 0}</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </SafeSection>

            {/* 评论区 */}
            <SafeSection
              label="comment-section"
              fallback={
                <div className="comment-section">
                  <div className="section-title">
                    <span>评论 (0)</span>
                  </div>
                  <div className="empty-comments">评论加载失败</div>
                </div>
              }
            >
              <div className="comment-section">
                <div className="section-title">
                  <span>评论 ({commentTotal || 0})</span>
                </div>

                {(comments || []).length === 0 && (
                  <div className="empty-comments">暂无评论，快来说点什么吧~</div>
                )}

                {(comments || []).map((c, ci) => (
                  <div key={c.id || `c-${ci}`} className="comment-item">
                    <img className="comment-avatar" src={c.avatar || ''} alt="" />
                    <div className="comment-body">
                      <div className="comment-top">
                        <span className="comment-name">{c.nickname || '匿名'}</span>
                        <span className="comment-time">{formatTime(c.created_at)}</span>
                      </div>
                      <div className="comment-content">{c.content || ''}</div>
                      <div className="comment-actions">
                        <span onClick={() => setReplyTo({ id: c.id, user_id: c.user_id || 0, nickname: c.nickname || '', parent_id: c.id })}>
                          💬 回复
                        </span>
                      </div>

                      {/* 子评论 */}
                      {c.replies && c.replies.length > 0 && (
                        <div className="sub-comments">
                          {c.replies.map((r, ri) => (
                            <div key={r.id || `r-${ri}`} className="sub-comment-item">
                              <img src={r.avatar || ''} alt="" />
                              <div>
                                <span className="sub-comment-name">{r.nickname || '匿名'}</span>
                                {r.reply_to_nickname && (
                                  <span className="reply-to">回复 {r.reply_to_nickname}</span>
                                )}
                                <span className="sub-comment-content">: {r.content || ''}</span>
                              </div>
                            </div>
                          ))}
                          {c.reply_count > c.replies.length && (
                            <div className="more-replies">查看全部 {c.reply_count} 条回复</div>
                          )}
                        </div>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </SafeSection>

            <div style={{ height: 80 }} />
          </div>
        </SafeSection>

        {/* 底部操作栏 */}
        <SafeSection label="bottom-bar">
          <div className="article-bottom-bar">
            <div
              className="comment-input"
              onClick={() => commentInputRef.current?.focus()}
            >
              {replyTo ? `回复 @${replyTo.nickname || ''}` : '说点什么...'}
            </div>
            <div className="bottom-actions">
              <div className={`action-item ${article?.is_liked ? 'active' : ''}`} onClick={handleLike}>
                <span className="action-icon">{article?.is_liked ? '❤️' : '🤍'}</span>
                <span className="action-text">{(article?.likes_count || 0)}</span>
              </div>
              <div className="action-item" onClick={() => commentInputRef.current?.focus()}>
                <span className="action-icon">💬</span>
                <span className="action-text">{(article?.comments_count || 0)}</span>
              </div>
              {article?.reward_enabled && (article?.user_id || 0) !== 1 && !article?.preview_only && (
                <div className="action-item reward-btn" onClick={() => setShowRewardModal(true)}>
                  <span className="action-icon">💰</span>
                  <span className="action-text">打赏</span>
                </div>
              )}
              <div className="action-item" onClick={() => showToast('分享链接已复制')}>
                <span className="action-icon">↗</span>
                <span className="action-text">分享</span>
              </div>
            </div>
          </div>
        </SafeSection>

        {/* 评论输入面板 */}
        <SafeSection label="comment-input-bar">
          {replyTo && (
            <div className="reply-bar">
              <span>回复 @{replyTo.nickname || ''}</span>
              <span className="cancel-reply" onClick={() => setReplyTo(null)}>✕</span>
            </div>
          )}
          <div className="comment-input-bar">
            <input
              ref={commentInputRef}
              type="text"
              placeholder={replyTo ? `回复 @${replyTo.nickname || ''}` : '友善评论，理性发言'}
              value={commentText}
              onChange={(e) => setCommentText(e.target.value)}
              onKeyPress={(e) => e.key === 'Enter' && submitComment()}
            />
            <button
              className={`send-btn ${(commentText || '').trim() ? 'active' : ''}`}
              onClick={submitComment}
              disabled={!(commentText || '').trim()}
            >
              发送
            </button>
          </div>
        </SafeSection>

        {/* 密码解锁弹窗 */}
        <SafeSection label="password-modal">
          {showPasswordModal && (
            <div className="modal-overlay" onClick={() => setShowPasswordModal(false)}>
              <div className="modal-content" onClick={e => e.stopPropagation()}>
                <div className="modal-title">输入密码查看文章</div>
                <p className="modal-desc">该文章受密码保护，请输入访问密码</p>
                <input
                  type="password"
                  className="modal-input"
                  placeholder="请输入密码"
                  value={passwordInput}
                  onChange={(e) => setPasswordInput(e.target.value)}
                  onKeyPress={(e) => e.key === 'Enter' && handleUnlock()}
                />
                <div className="modal-actions">
                  <button className="modal-btn modal-btn-cancel" onClick={() => setShowPasswordModal(false)}>取消</button>
                  <button className="modal-btn modal-btn-primary" onClick={handleUnlock}>确定</button>
                </div>
              </div>
            </div>
          )}
        </SafeSection>

        {/* 付费购买弹窗 */}
        <SafeSection label="pay-modal">
          {showPayModal && (
            <div className="modal-overlay" onClick={() => setShowPayModal(false)}>
              <div className="modal-content" onClick={e => e.stopPropagation()}>
                <div className="modal-title">购买文章</div>
                <p className="modal-desc">《{article?.title || ''}》</p>
                <div className="pay-amount">¥{article?.price || 0}</div>
                <p className="modal-desc">当前余额支付</p>
                <div className="modal-actions">
                  <button className="modal-btn modal-btn-cancel" onClick={() => setShowPayModal(false)}>取消</button>
                  <button className="modal-btn modal-btn-primary" onClick={handlePay}>立即支付</button>
                </div>
              </div>
            </div>
          )}
        </SafeSection>

        {/* 打赏弹窗 */}
        <SafeSection label="reward-modal">
          {showRewardModal && (
            <div className="modal-overlay" onClick={() => setShowRewardModal(false)}>
              <div className="modal-content" onClick={e => e.stopPropagation()}>
                <div className="modal-title">打赏作者</div>
                <div className="reward-options">
                  {[1, 5, 10, 20, 50, 100].map(amount => (
                    <div
                      key={amount}
                      className={`reward-option ${rewardAmount === amount ? 'active' : ''}`}
                      onClick={() => setRewardAmount(amount)}
                    >
                      ¥{amount}
                    </div>
                  ))}
                </div>
                <div className="custom-reward">
                  <input
                    type="number"
                    placeholder="自定义金额"
                    value={rewardAmount === 'custom' ? '' : (rewardAmount || 0)}
                    onChange={(e) => setRewardAmount(parseFloat(e.target.value) || 0)}
                  />
                </div>
                <textarea
                  className="reward-message-input"
                  placeholder="想说点什么...（选填）"
                  value={rewardMessage}
                  onChange={(e) => setRewardMessage(e.target.value)}
                  maxLength={100}
                />
                <div className="modal-actions">
                  <button className="modal-btn modal-btn-cancel" onClick={() => setShowRewardModal(false)}>取消</button>
                  <button className="modal-btn modal-btn-primary" onClick={handleReward}>
                    打赏 ¥{rewardAmount || 0}
                  </button>
                </div>
              </div>
            </div>
          )}
        </SafeSection>

        {/* 打赏列表弹窗 */}
        <SafeSection label="reward-list-modal">
          {showRewardsList && (
            <div className="modal-overlay" onClick={() => setShowRewardsList(false)}>
              <div className="modal-content reward-list-modal" onClick={e => e.stopPropagation()}>
                <div className="modal-title">打赏记录</div>
                <div className="reward-list-scroll">
                  {(rewards || []).length === 0 && <div className="empty-state">暂无打赏</div>}
                  {(rewards || []).map((r, i) => (
                    <div key={r.id || `rw-${i}`} className="reward-list-item">
                      <img src={r.avatar || ''} alt="" />
                      <div className="reward-list-info">
                        <div className="reward-list-name">{r.nickname || '匿名'}</div>
                        {r.message && <div className="reward-list-msg">{r.message}</div>}
                        <div className="reward-list-time">{formatTime(r.created_at)}</div>
                      </div>
                      <div className="reward-list-amount">¥{r.amount || 0}</div>
                    </div>
                  ))}
                </div>
                <button className="modal-btn modal-btn-cancel full-width" onClick={() => setShowRewardsList(false)}>
                  关闭
                </button>
              </div>
            </div>
          )}
        </SafeSection>

      <style>{`
        .article-detail {
          background: #fff;
          min-height: 100%;
        }
        .article-detail-header {
          padding: 16px;
          border-bottom: 1px solid #f0f0f0;
        }
        .article-detail-title {
          font-size: 22px;
          font-weight: 700;
          line-height: 1.4;
          color: #1a1a1a;
          margin: 0 0 12px 0;
        }
        .article-detail-meta {}
        .article-author-info {
          display: flex;
          align-items: center;
          gap: 10px;
        }
        .article-author-info img {
          width: 40px;
          height: 40px;
          border-radius: 50%;
        }
        .author-name {
          font-size: 14px;
          font-weight: 600;
          color: #333;
        }
        .author-stats {
          font-size: 12px;
          color: #999;
          display: flex;
          gap: 6px;
          margin-top: 2px;
        }
        .cat-inline {
          color: #2E7CF6;
        }
        .article-detail-cover {
          width: 100%;
          max-height: 300px;
          overflow: hidden;
          background: #f5f5f5;
        }
        .article-detail-cover img {
          width: 100%;
          height: auto;
        }
        .article-detail-content {
          padding: 20px 16px;
          font-size: 16px;
          line-height: 1.8;
          color: #333;
        }
        .article-detail-content :deep img,
        .article-detail-content img {
          max-width: 100%;
          border-radius: 8px;
          margin: 12px 0;
        }
        .article-detail-content h2 {
          font-size: 18px;
          font-weight: 700;
          margin: 24px 0 12px;
          color: #1a1a1a;
        }
        .article-detail-content h3 {
          font-size: 16px;
          font-weight: 600;
          margin: 20px 0 10px;
          color: #1a1a1a;
        }
        .article-detail-content p {
          margin: 12px 0;
        }

        .pay-wall {
          margin: 20px 16px;
          padding: 24px;
          background: linear-gradient(135deg, #fff8f0 0%, #fff0e6 100%);
          border-radius: 12px;
          text-align: center;
          border: 1px solid #ffe0c2;
        }
        .pay-wall-icon { font-size: 32px; margin-bottom: 8px; }
        .pay-wall-title { font-size: 16px; font-weight: 600; color: #333; margin-bottom: 4px; }
        .pay-wall-desc { font-size: 13px; color: #999; margin-bottom: 16px; }
        .pay-wall-btn {
          background: linear-gradient(135deg, #ff9d3a 0%, #ff6b00 100%);
          color: #fff;
          border: none;
          padding: 12px 32px;
          border-radius: 24px;
          font-size: 15px;
          font-weight: 600;
          cursor: pointer;
        }

        .article-tags {
          display: flex;
          gap: 8px;
          padding: 0 16px 16px;
        }
        .tag {
          padding: 3px 10px;
          border-radius: 12px;
          font-size: 12px;
          background: #f5f5f5;
          color: #666;
        }
        .tag-success {
          background: #e6f7ed;
          color: #00b578;
        }

        .reward-section {
          margin: 16px;
          padding: 16px;
          background: #faf9ff;
          border-radius: 12px;
          border: 1px solid #eee8ff;
        }
        .reward-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 12px;
          font-size: 14px;
          font-weight: 600;
          color: #333;
        }
        .reward-count {
          font-size: 12px;
          color: #999;
          font-weight: 400;
        }
        .reward-avatars {
          display: flex;
          gap: -8px;
          flex-wrap: wrap;
        }
        .reward-avatar-item {
          position: relative;
          margin-left: -6px;
        }
        .reward-avatar-item:first-child { margin-left: 0; }
        .reward-avatar-item img {
          width: 32px;
          height: 32px;
          border-radius: 50%;
          border: 2px solid #fff;
        }
        .reward-amount {
          position: absolute;
          bottom: -6px;
          right: -4px;
          background: #ff6b00;
          color: #fff;
          font-size: 10px;
          padding: 1px 4px;
          border-radius: 8px;
          white-space: nowrap;
        }

        .comment-section {
          padding: 16px;
          border-top: 8px solid #f5f5f5;
        }
        .section-title {
          font-size: 16px;
          font-weight: 600;
          color: #333;
          margin-bottom: 16px;
        }
        .empty-comments {
          text-align: center;
          padding: 30px;
          color: #bbb;
          font-size: 13px;
        }
        .comment-item {
          display: flex;
          gap: 10px;
          margin-bottom: 16px;
        }
        .comment-avatar {
          width: 36px;
          height: 36px;
          border-radius: 50%;
          flex-shrink: 0;
        }
        .comment-body { flex: 1; min-width: 0; }
        .comment-top {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 4px;
        }
        .comment-name {
          font-size: 13px;
          color: #666;
          font-weight: 500;
        }
        .comment-time {
          font-size: 11px;
          color: #bbb;
        }
        .comment-content {
          font-size: 14px;
          color: #333;
          line-height: 1.5;
          word-break: break-word;
        }
        .comment-actions {
          margin-top: 6px;
          display: flex;
          gap: 16px;
        }
        .comment-actions span {
          font-size: 12px;
          color: #999;
          cursor: pointer;
        }
        .sub-comments {
          margin-top: 8px;
          padding: 10px;
          background: #f8f8f8;
          border-radius: 8px;
        }
        .sub-comment-item {
          display: flex;
          gap: 6px;
          font-size: 13px;
          margin-bottom: 6px;
        }
        .sub-comment-item:last-child { margin-bottom: 0; }
        .sub-comment-item img {
          width: 22px;
          height: 22px;
          border-radius: 50%;
          flex-shrink: 0;
        }
        .sub-comment-item > div {
          color: #666;
          line-height: 1.5;
        }
        .sub-comment-name {
          color: #2E7CF6;
          font-weight: 500;
        }
        .reply-to {
          color: #999;
          margin: 0 4px;
        }
        .sub-comment-content {
          color: #333;
        }
        .more-replies {
          font-size: 12px;
          color: #2E7CF6;
          margin-top: 4px;
          cursor: pointer;
        }

        /* 底部操作栏 */
        .article-bottom-bar {
          position: fixed;
          bottom: 0;
          left: 0;
          right: 0;
          background: #fff;
          border-top: 1px solid #f0f0f0;
          padding: 8px 12px;
          padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
          display: flex;
          align-items: center;
          gap: 12px;
          z-index: 100;
        }
        .comment-input {
          flex: 1;
          padding: 8px 14px;
          background: #f5f5f5;
          border-radius: 20px;
          font-size: 14px;
          color: #999;
        }
        .bottom-actions {
          display: flex;
          gap: 6px;
        }
        .action-item {
          display: flex;
          flex-direction: column;
          align-items: center;
          font-size: 10px;
          color: #666;
          padding: 0 6px;
          cursor: pointer;
          min-width: 36px;
        }
        .action-item.active {
          color: #ff4757;
        }
        .action-icon {
          font-size: 20px;
          margin-bottom: 2px;
        }
        .reward-btn {
          color: #ff9500;
        }

        /* 评论输入条 */
        .reply-bar {
          position: fixed;
          bottom: 50px;
          left: 0;
          right: 0;
          background: #fff8e6;
          padding: 6px 16px;
          font-size: 13px;
          color: #996600;
          display: flex;
          justify-content: space-between;
          border-top: 1px solid #ffe8a3;
          z-index: 101;
        }
        .cancel-reply {
          cursor: pointer;
          color: #999;
        }
        .comment-input-bar {
          position: fixed;
          bottom: 0;
          left: 0;
          right: 0;
          background: #fff;
          border-top: 1px solid #f0f0f0;
          padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px));
          display: flex;
          gap: 8px;
          z-index: 102;
          transform: translateY(100%);
          transition: transform 0.25s;
        }
        .comment-input-bar:focus-within {
          transform: translateY(0);
        }
        .comment-input-bar input {
          flex: 1;
          padding: 8px 14px;
          border: none;
          background: #f5f5f5;
          border-radius: 20px;
          font-size: 14px;
          outline: none;
        }
        .send-btn {
          padding: 8px 16px;
          border: none;
          border-radius: 20px;
          background: #ddd;
          color: #fff;
          font-size: 14px;
          cursor: not-allowed;
        }
        .send-btn.active {
          background: var(--primary-color, #2E7CF6);
          cursor: pointer;
        }

        /* 弹窗通用 */
        .modal-overlay {
          position: fixed;
          inset: 0;
          background: rgba(0,0,0,0.5);
          display: flex;
          align-items: center;
          justify-content: center;
          z-index: 999;
          padding: 20px;
        }
        .modal-content {
          background: #fff;
          border-radius: 16px;
          padding: 24px;
          width: 100%;
          max-width: 340px;
          max-height: 80vh;
          overflow-y: auto;
        }
        .modal-title {
          font-size: 17px;
          font-weight: 600;
          text-align: center;
          margin-bottom: 8px;
          color: #1a1a1a;
        }
        .modal-desc {
          font-size: 13px;
          color: #999;
          text-align: center;
          margin-bottom: 16px;
        }
        .modal-input {
          width: 100%;
          padding: 10px 14px;
          border: 1px solid #eee;
          border-radius: 8px;
          font-size: 14px;
          margin-bottom: 16px;
          outline: none;
          box-sizing: border-box;
        }
        .modal-input:focus { border-color: var(--primary-color, #2E7CF6); }
        .modal-actions {
          display: flex;
          gap: 10px;
          margin-top: 8px;
        }
        .modal-btn {
          flex: 1;
          padding: 12px;
          border: none;
          border-radius: 24px;
          font-size: 14px;
          font-weight: 600;
          cursor: pointer;
        }
        .modal-btn-cancel {
          background: #f5f5f5;
          color: #666;
        }
        .modal-btn-primary {
          background: var(--primary-color, #2E7CF6);
          color: #fff;
        }
        .full-width {
          width: 100%;
          margin-top: 12px;
        }
        .pay-amount {
          text-align: center;
          font-size: 36px;
          font-weight: 700;
          color: #ff6b00;
          margin: 12px 0;
        }
        .reward-options {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: 10px;
          margin-bottom: 12px;
        }
        .reward-option {
          padding: 12px;
          border: 1px solid #eee;
          border-radius: 8px;
          text-align: center;
          font-size: 15px;
          font-weight: 500;
          color: #333;
          cursor: pointer;
          transition: all .2s;
        }
        .reward-option.active {
          border-color: var(--primary-color, #2E7CF6);
          background: #e8f2ff;
          color: var(--primary-color, #2E7CF6);
        }
        .custom-reward input {
          width: 100%;
          padding: 10px 14px;
          border: 1px solid #eee;
          border-radius: 8px;
          font-size: 14px;
          text-align: center;
          margin-bottom: 12px;
          box-sizing: border-box;
          outline: none;
        }
        .reward-message-input {
          width: 100%;
          min-height: 60px;
          padding: 10px 14px;
          border: 1px solid #eee;
          border-radius: 8px;
          font-size: 13px;
          resize: none;
          margin-bottom: 12px;
          box-sizing: border-box;
          outline: none;
          font-family: inherit;
        }

        .reward-list-modal {
          max-height: 70vh;
        }
        .reward-list-scroll {
          max-height: 300px;
          overflow-y: auto;
        }
        .reward-list-item {
          display: flex;
          align-items: center;
          gap: 10px;
          padding: 10px 0;
          border-bottom: 1px solid #f5f5f5;
        }
        .reward-list-item img {
          width: 36px;
          height: 36px;
          border-radius: 50%;
        }
        .reward-list-info { flex: 1; min-width: 0; }
        .reward-list-name {
          font-size: 14px;
          font-weight: 500;
          color: #333;
        }
        .reward-list-msg {
          font-size: 12px;
          color: #666;
          margin-top: 2px;
        }
        .reward-list-time {
          font-size: 11px;
          color: #bbb;
          margin-top: 2px;
        }
        .reward-list-amount {
          font-size: 15px;
          font-weight: 600;
          color: #ff6b00;
        }

        .loading-state {
          text-align: center;
          padding: 60px;
          color: #999;
        }
        .empty-state {
          text-align: center;
          padding: 40px;
          color: #999;
          font-size: 14px;
        }
        .icon-btn {
          font-size: 18px;
          cursor: pointer;
          padding: 4px 8px;
        }
      `}</style>
      </div>
    </ArticleErrorBoundary>
  );
}

Object.assign(window, { ArticleDetailPage });
