import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useParams, Link } from 'react-router-dom';
import * as blogApi from '../api/blog.js';
import { me } from '../api/auth.js';
import { getToken } from '../api/client.js';
import MarkdownRenderer from '../components/MarkdownRenderer.jsx';
import { showSnackbar } from '../lib/utils.js';

/** 字数统计：剥离 markdown 符号与 [image:]/[file:] 标签后，中文字符 + 英文单词数 */
function countWords(content) {
  const plain = String(content || '')
    .replace(/\[image:[^\]]*\]|\[file:[^\]]*\]/g, '')
    .replace(/[#*`\[\]()>|~_!-]/g, '');
  const cjk = (plain.match(/[\u4e00-\u9fff\u3400-\u4dbf]/g) || []).length;
  const words = plain.replace(/[\u4e00-\u9fff\u3400-\u4dbf]/g, ' ').trim().split(/\s+/).filter(Boolean).length;
  return cjk + words;
}

/**
 * 博客详情页（路由 /blog/:id）：
 * 正文（MarkdownRenderer）+ 阅读量/标签/点赞 + 目录/字数 + 上一篇/下一篇 +
 * 嵌套评论（parent_id 回复）。
 */
export default function BlogDetail() {
  const { id } = useParams();
  const [post, setPost] = useState(null);
  const [comments, setComments] = useState([]);
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [commentText, setCommentText] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [prevnext, setPrevnext] = useState(null);
  const [like, setLike] = useState({ liked: false, count: 0 });
  const [toc, setToc] = useState([]);
  const [replyTo, setReplyTo] = useState(null); // {id, name}

  const load = useCallback(async () => {
    setLoading(true);
    setError('');
    setReplyTo(null);
    try {
      const [p, cs, pn, lk] = await Promise.all([
        blogApi.getPost(id),
        blogApi.listComments(id),
        blogApi.getPrevNext(id),
        blogApi.getLikeState(id),
      ]);
      setPost(p);
      setComments(cs || []);
      setPrevnext(pn);
      setLike(lk || { liked: false, count: 0 });
    } catch (e) {
      setError(e.message || '加载失败');
    } finally {
      setLoading(false);
    }
  }, [id]);

  useEffect(() => {
    load();
    if (getToken()) {
      me().then(setUser).catch(() => setUser(null));
    } else {
      setUser(null);
    }
  }, [load]);

  const canEdit = user && post && (user.role === 'admin' || user.id === post.author_id);
  const wordCount = useMemo(() => (post ? countWords(post.content) : 0), [post]);

  // 目录：从已渲染的 .md-body 提取 h2（仅一级章节）打锚点；短文章（<500 字）不提取
  useEffect(() => {
    if (!post) return;
    if (wordCount < 500) { setToc([]); return; }
    const body = document.querySelector('.blog-article .md-body');
    if (!body) { setToc([]); return; }
    const items = [...body.querySelectorAll('h2')].map((h, i) => {
      if (!h.id) h.id = 'toc-' + i;
      return { id: h.id, text: (h.textContent || '').trim(), level: 2 };
    });
    setToc(items);
  }, [post, wordCount]);

  const tags = useMemo(() => String(post?.tags || '').split(',').map((t) => t.trim()).filter(Boolean), [post]);

  // ── 点赞（乐观更新）──
  const toggleLike = async () => {
    if (!user) { showSnackbar('登录后可以点赞'); return; }
    const next = !like.liked;
    setLike((s) => ({ liked: next, count: Math.max(0, s.count + (next ? 1 : -1)) }));
    try {
      const r = next ? await blogApi.likePost(id) : await blogApi.unlikePost(id);
      setLike({ liked: r.liked, count: r.count });
    } catch (e) {
      setLike((s) => ({ liked: !s.liked, count: Math.max(0, s.count + (s.liked ? 1 : -1)) }));
      showSnackbar(e.message);
    }
  };

  // ── 嵌套评论 ──
  const childrenOf = useCallback((pid) => comments.filter((c) => c.parent_id === pid), [comments]);
  const rootComments = comments.filter((c) => !c.parent_id);

  const renderComment = (c, depth = 0) => {
    const kids = childrenOf(c.id);
    return (
      <div key={c.id} className={'reply-item' + (depth > 0 ? ' reply-child' : '')}>
        <div className="reply-meta">
          <strong>{c.author_name || '游客'}</strong> · {c.created_at}
          {kids.length > 0 && <span className="reply-count">回复 {kids.length}</span>}
        </div>
        <div className="reply-body">{c.content}</div>
        {user && (
          <button
            className="btn btn-text btn-sm reply-btn"
            onClick={() => {
              setReplyTo({ id: c.id, name: c.author_name || '游客' });
              setCommentText(`@${c.author_name || '游客'} `);
            }}
          >
            <span className="material-icons" style={{ fontSize: 14 }}>reply</span> 回复
          </button>
        )}
        {kids.length > 0 && (
          <div className="reply-children">
            {kids.map((k) => renderComment(k, depth + 1))}
          </div>
        )}
      </div>
    );
  };

  const submitComment = async () => {
    const content = commentText.trim();
    if (!content) { showSnackbar('评论不能为空'); return; }
    setSubmitting(true);
    try {
      await blogApi.createComment(id, content, replyTo ? replyTo.id : 0);
      showSnackbar('评论已发表');
      setCommentText('');
      setReplyTo(null);
      await load();
    } catch (e) {
      showSnackbar(e.message);
    }
    setSubmitting(false);
  };

  if (loading) {
    return <div className="loading"><div className="spinner"></div></div>;
  }

  if (error || !post) {
    return (
      <div className="empty-state">
        <div className="empty-icon">⚠️</div>
        <p>{error || '文章不存在'}</p>
        <Link to="/blog.html" className="btn btn-tonal btn-sm" style={{ marginTop: 12 }}>返回博客</Link>
      </div>
    );
  }

  return (
    <div className="article-layout">
      <div className="blog-article article-main">
      <Link to="/blog.html" className="btn btn-text btn-sm" style={{ marginBottom: 16 }}>
        <span className="material-icons" style={{ fontSize: 16 }}>arrow_back</span> 返回列表
      </Link>

      <h1 className="article-title">{post.title}</h1>

      <div className="article-meta">
        {post.author_name || '管理员'} · {post.created_at}
        <span className="meta-stat" title="阅读量">
          <span className="material-icons" style={{ fontSize: 15 }}>visibility</span> {post.views || 0}
        </span>
        <span className="meta-stat" title="字数">约 {wordCount} 字</span>
      </div>

      {tags.length > 0 && (
        <div className="article-tags">
          {tags.map((t) => (
            <Link key={t} to={`/tag/${encodeURIComponent(t)}`} className="chip article-tag-chip">{t}</Link>
          ))}
        </div>
      )}

      <div className="article-actions">
        <button className={'btn like-btn' + (like.liked ? ' liked' : '')} onClick={toggleLike} title="点赞">
          <span className="material-icons" style={{ fontSize: 18 }}>{like.liked ? 'favorite' : 'favorite_border'}</span>
          <span className="like-count">{like.count}</span>
        </button>
        {canEdit && (
          <Link to={`/write.html?edit=${post.id}`} className="btn btn-tonal btn-sm">编辑</Link>
        )}
      </div>

      <MarkdownRenderer content={post.content} useMarkdown={post.use_markdown} />

      {/* 上一篇 / 下一篇 */}
      {prevnext && (prevnext.prev || prevnext.next) && (
        <nav className="prevnext-nav">
          <div className="pn-col pn-prev">
            {prevnext.prev ? (
              <Link to={`/blog/${prevnext.prev.id}`}>
                <span className="pn-label">上一篇</span>
                <span className="pn-title">{prevnext.prev.title}</span>
              </Link>
            ) : (
              <span className="pn-disabled"><span className="pn-label">上一篇</span><span className="pn-title">没有了</span></span>
            )}
          </div>
          <div className="pn-col pn-next">
            {prevnext.next ? (
              <Link to={`/blog/${prevnext.next.id}`}>
                <span className="pn-label">下一篇</span>
                <span className="pn-title">{prevnext.next.title}</span>
              </Link>
            ) : (
              <span className="pn-disabled"><span className="pn-label">下一篇</span><span className="pn-title">没有了</span></span>
            )}
          </div>
        </nav>
      )}

      <hr style={{ border: 'none', borderTop: '1px solid var(--md-ref-outline-variant)', margin: '32px 0' }} />
      <h4 style={{ fontWeight: 500, marginBottom: 16 }}>评论 ({comments.length})</h4>

      {comments.length === 0 ? (
        <p className="text-muted" style={{ fontSize: 14 }}>暂无评论</p>
      ) : (
        <div className="comment-list">
          {rootComments.map((c) => renderComment(c))}
        </div>
      )}

      {user ? (
        <div className="comment-form">
          {replyTo && (
            <div className="reply-to-hint">
              <span className="material-icons" style={{ fontSize: 15 }}>reply</span>
              回复 <strong>@{replyTo.name}</strong>
              <button
                className="btn btn-text btn-sm"
                onClick={() => { setReplyTo(null); setCommentText(''); }}
              >
                <span className="material-icons" style={{ fontSize: 15 }}>close</span> 取消
              </button>
            </div>
          )}
          <div style={{ display: 'flex', gap: 8, marginTop: replyTo ? 8 : 0 }}>
            <textarea
              value={commentText}
              onChange={(e) => setCommentText(e.target.value)}
              placeholder={replyTo ? `回复 @${replyTo.name}...` : '写下你的评论...'}
              style={{ flex: 1, minHeight: 60, fontSize: 14 }}
            />
            <button className="btn btn-filled btn-sm" style={{ alignSelf: 'flex-end' }} onClick={submitComment} disabled={submitting}>
              发表评论
            </button>
          </div>
        </div>
      ) : (
        <p className="text-muted" style={{ marginTop: 12, fontSize: 14 }}>
          <Link to="/login.html" style={{ color: 'var(--md-ref-primary)' }}>登录</Link>后可以评论
        </p>
      )}
        </div>

        {/* 侧边目录（仅 h2 章节；短文章 <500 字不显示） */}
        {toc.length > 0 && (
          <aside className="article-toc-side">
            <div className="toc-title">
              <span className="material-icons" style={{ fontSize: 16 }}>format_list_bulleted</span>
              目录 <span className="toc-count">{toc.length}</span>
            </div>
            <ul className="toc-list">
              {toc.map((t) => (
                <li key={t.id} className="toc-item">
                  <a
                    href={'#' + t.id}
                    onClick={(e) => {
                      e.preventDefault();
                      const el = document.getElementById(t.id);
                      if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
                    }}
                  >
                    {t.text}
                  </a>
                </li>
              ))}
            </ul>
          </aside>
        )}
    </div>
  );
}
