import React, { useState, useEffect, useRef } from 'react';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import { 
  getPostDetail,
  addPostComment,
  likePost,
  deletePost
} from '../api/helpPost';
import {
  likePostComment,
  getCommentReplies,
  addCommentReply,
  deleteComment
} from '../api/helpComment';
import './HelpDetail.css';

const HelpDetail = () => {
  const { id } = useParams();
  const navigate = useNavigate();
  const location = useLocation();
  const fileInputRef = useRef(null);
  const [post, setPost] = useState(null);
  const [comments, setComments] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [newComment, setNewComment] = useState('');
  const [replyContent, setReplyContent] = useState('');
  const [replyImage, setReplyImage] = useState([]);
  const [commentImage, setCommentImage] = useState([]);
  const [expandedReplies, setExpandedReplies] = useState({}); // 记录哪些评论的回复是展开的
  const [loadingReplies, setLoadingReplies] = useState({});
  const [setReplyingTo] = useState(null);
  

  const [activeReplyId, setActiveReplyId] = useState(null);
    const [replyModal, setReplyModal] = useState({
      visible: false,
      replyingTo: null,
      replyingToUsername: '',
      isReply: false
    });
  
    // 确保openReplyModal接收username参数
  const openReplyModal = (commentId, username) => {
    setReplyModal({
      visible: true,
      replyingTo: commentId,
      replyingToUsername: username,  // 确保这里接收username
      isReply: false
    });
  };
  
    // 关闭回复弹窗
    const closeReplyModal = () => {
      setReplyModal({
        visible: false,
        replyingTo: null,
        replyingToUsername: '',
        isReply: false
      });
      setReplyContent('');
    };

    const Comment = ({ comment, onLike, onReply, onDelete, isReply = false }) => {
      return (
        <div className={`comment-container ${isReply ? "is-reply" : ""}`}>
          <div className="comment-item">
            <div className="comment-avatar">
              {(comment.authorId || "?").charAt(0)} {/* 修复点 */}
            </div>
            <div className="comment-content">
              <div className="comment-header">
                <span className="comment-user">{comment.authorId || "匿名用户"}</span>
                {comment.replyTo && (
                  <span className="reply-to">回复 @{comment.replyTo}</span>
                )}
                <span className="comment-time">
                  {new Date(comment.createTime).toLocaleString()}
                </span>
              </div>
              <p className="comment-text">{comment.content}</p>
              {/* 添加评论图片展示 */}
              {comment.imageUrl && (
                <div className="comment-image-container">
                  <img 
                    src={`http://localhost:8088${comment.imageUrl}`} 
                    alt="评论图片" 
                    className="comment-image"
                    onClick={() => window.open(comment.imageUrl, '_blank')}
                  />
                </div>
              )}
              <div className="comment-actions">
                <button onClick={() => onLike(comment.id)}>
                  👍 ({comment.likeCount || 0})
                </button>
                <button onClick={() => onReply(comment.id, comment.authorId)}>
                  回复
                </button>
                {comment.authorId === localStorage.getItem('username') && (
                  <button 
                    className="delete-comment-btn"
                    onClick={() => onDelete(comment.id)}
                  >
                    删除
                  </button>
                )}
              </div>
            </div>
          </div>
        </div>
      );
    };

      // 递归渲染评论组件
  const renderComment = (comment, depth = 0) => {
    return (
      <div key={comment.id} style={{ marginLeft: `${depth * 30}px` }}>
        <Comment
          comment={comment}
          onLike={handleLikeComment}
          onReply={openReplyModal}
          isReply={depth > 0}
          onDelete={handleDeleteComment}
        />
        
        {/* 递归渲染所有回复 */}
        {comment.replies && comment.replies.map(reply => 
          renderComment(reply, depth + 1)
        )}
      </div>
    );
  };


   const fetchPostDetail = async () => {
      try {
        setLoading(true);
        const response = await getPostDetail(id);
        console.log('API Response:', JSON.parse(JSON.stringify(response.data.data.comments))); // 深度拷贝避免Proxy影响
        setPost(response.data.data.post);
        setComments(response.data.data.comments);
      } catch (err) {
        setError(err.response?.data?.message || '获取帖子详情失败');
      } finally {
        setLoading(false);
      }
    };
  
    useEffect(() => {
      fetchPostDetail();
    }, [id]);
  
    // 点赞帖子
    const handleLikePost = async () => {
      try {
        await likePost(id);
        setPost(prev => ({
          ...prev,
          likeCount: prev.likeCount + 1
        }));
      } catch (err) {
        setError('点赞失败: ' + (err.response?.data?.message || err.message));
      }
    };

     // 添加删除处理函数
     const handleDeletePost = async (postId) => {
      if (window.confirm('确定要删除这个帖子吗？所有评论也将被删除！')) {
        try {
          const username = localStorage.getItem('username');
          await deletePost(postId, username);
          navigate('/dashboard/help'); // 删除成功后返回求助区
        } catch (err) {
          setError('删除失败: ' + (err.response?.data?.message || err.message));
        }
      }
    };
  
    const handleCommentSubmit = async (e) => {
      e.preventDefault();
      if (!newComment.trim()) return;
      
      try {
        const username = localStorage.getItem('username');
        const response = await addPostComment(id, {
          content: newComment,
          authorId: username
        });
    
        // 修改这里的响应处理逻辑
        if (response.data && response.data.code === 200) {
          await fetchPostDetail();
          
          setNewComment('');
        } else {
          setError(response.data.message || '评论失败');
        }
      } catch (err) {
        setError('评论失败: ' + (err.response?.data?.message || err.message));
      }
    };
    
    
    const handleLikeComment = async (commentId) => {
      try {
        await likePostComment(commentId);
        
        // 递归更新评论点赞数
        const updateComments = (comments) => {
          return comments.map(comment => {
            // 当前评论匹配
            if (comment.id === commentId) {
              return { ...comment, likeCount: comment.likeCount + 1 };
            }
            
            // 递归处理回复
            if (comment.replies && comment.replies.length > 0) {
              return {
                ...comment,
                replies: updateComments(comment.replies)
              };
            }
            
            return comment;
          });
        };
    
        setComments(prev => updateComments(prev));
      } catch (err) {
        setError('点赞失败: ' + (err.response?.data?.message || err.message));
      }
    };

    const handleDeleteComment = async (commentId) => {
      if (window.confirm('确定要删除这条评论吗？')) {
        try {
          const username = localStorage.getItem('username');
          await deleteComment(commentId, username);
          await fetchPostDetail(); // 刷新评论列表
        } catch (err) {
          setError('删除失败: ' + (err.response?.data?.message || err.message));
        }
      }
    };


    // 修改startReply函数
    const startReply = (commentId) => {
      if (activeReplyId === commentId) {
        // 如果点击的是已经激活的回复按钮，则关闭
        setActiveReplyId(null);
        setReplyingTo(null);
      } else {
        // 否则打开新的回复框
        setActiveReplyId(commentId);
        setReplyingTo(commentId);
      }
    };
  
    const handleReplySubmit = async (e) => {
      e.preventDefault();
      if (!replyContent.trim()) return;
    
      try {
        const username = localStorage.getItem('username');
        const response = await addCommentReply(replyModal.replyingTo, {
          authorId: username,
          content: replyContent,
          image: replyImage
        });
    
        console.log('回复响应:', response.data); // 调试
        
        if (response.data && response.data.code === 200) {
          await fetchPostDetail();
          setReplyContent('');
          closeReplyModal();
        }
      } catch (err) {
        console.error('回复错误:', err);
        setError('回复失败: ' + (err.response?.data?.message || err.message));
      }
    };
  
  
    // 返回按钮
    const handleBack = () => {
      const fromTab = location.state?.fromTab || 'share';
      navigate(`/dashboard/help`);
    };
  
    

  const handleMarkSolved = () => {
    // TODO: 实现标记为已解决的功能
    setPost(prev => ({
      ...prev,
      isSolved: !prev.isSolved
    }));
  };

  // const handleImageUpload = (e) => {
  //   const files = Array.from(e.target.files);
  //   const newImages = files.map(file => URL.createObjectURL(file));
  //   setImages(prev => [...prev, ...newImages]);
  // };

  // const handleRemoveImage = (index) => {
  //   setImages(prev => prev.filter((_, i) => i !== index));
  // };

  

  if (loading) return <div className="loading">加载中...</div>;
  if (error) return <div className="error">{error}</div>;
  if (!post) return <div className="error">帖子不存在</div>;

  return (
    <div className="help-detail-container">
      <button className="back-button" onClick={handleBack}>
        &larr; 返回求助区
      </button>
      
      <div className={`help-post ${post.isSolved ? 'solved' : ''}`}>
        <div className="post-header">
          <img 
            src={post.authorAvatar || 'https://via.placeholder.com/40'} 
            alt={post.authorId} 
            className="post-avatar" 
          />
          <div className="post-meta">
            <div className="post-author">{post.authorId}</div>
            <div className="post-date">
              {new Date(post.createTime).toLocaleString()}
              </div>
          </div>
          {post.isSolved && <span ClassName="solved-badge">已解决</span>}
          <div classname="delete-post">
            {post.authorId === localStorage.getItem('username') && (
              <button 
                className="delete-button"
                onClick={() => handleDeletePost(post.id)}
              >
                删除帖子
              </button>
            )}
          </div>
        </div>
        
        <h1 className="post-title">{post.title}</h1>
        
        <div className="post-content">
          {post.content.split('\n').map((para, i) => (
            <p key={i}>{para}</p>
          ))}
          {/* 添加帖子图片展示 */}
          {post.imageUrl && (
            <div className="post-image-container">
              <img 
                src={`http://localhost:8088${post.imageUrl}`} 
                alt="帖子图片" 
                className="post-image"
                // onError={(e) => {
                //   e.target.onerror = null; 
                //   e.target.src = 'https://via.placeholder.com/400x300?text=图片加载失败';
                //   console.error('图片加载失败:', post.imageUrl);
                // }}
              />
            </div>
          )}
        </div>
        
        <div className="post-actions">
          <button 
            className={`like-button ${post.isLiked ? 'liked' : ''}`}
            onClick={handleLikePost}
          >
            👍 点赞 ({post.likeCount})
          </button>
          <button 
            className={`solve-button ${post.isSolved ? 'solved' : ''}`}
            onClick={handleMarkSolved}
          >
            {post.isSolved ? '✓ 已解决' : '标记为已解决'}
          </button>
        </div>
      </div>
      
       <div className="comments-section">
        <h2>评论 ({post.replyCount})</h2>
        
        <form onSubmit={handleCommentSubmit} className="comment-form">
          <textarea
            value={newComment}
            onChange={(e) => setNewComment(e.target.value)}
            placeholder="写下你的评论..."
            rows="3"
            required
          />
          <button type="submit">发表评论</button>

          {/* 图片上传部分 */}
          <div className="form-group">
            <div className="upload-image-btn">
              <input 
                type="file" 
                accept="image/*" 
                onChange={(e) => setCommentImage(e.target.files[0])} 
                data-testid="comment-image-input"  
              />
            </div>
          </div>
        </form>
        
        
        <div className="comment-list">
          {comments.map(comment => renderComment(comment))}
        </div>

        {replyModal.visible && (
          <div className="reply-modal-overlay">
            <div className="reply-modal">
              <div className="modal-header">
                <h3>回复 @{replyModal.replyingToUsername}</h3>
                <button onClick={closeReplyModal} className="close-modal">&times;</button>
              </div>
              <form onSubmit={handleReplySubmit}>
                <textarea
                  value={replyContent}
                  onChange={(e) => setReplyContent(e.target.value)}
                  placeholder={`回复 @${replyModal.replyingToUsername}...`}
                  rows="5"
                  autoFocus
                  required
                />

                {/* 图片上传部分 */}
                <div className="form-group">
                  <div className="upload-image-btn">
                    <input 
                      type="file" 
                      accept="image/*" 
                      onChange={(e) => setReplyImage(e.target.files[0])} 
                    />
                  </div>
                </div>

                <div className="modal-actions">
                  <button type="button" onClick={closeReplyModal} className="cancel-btn">
                    取消
                  </button>
                  <button type="submit" className="submit-btn">
                    发送回复
                  </button>
                </div>
              </form>
            </div>
          </div>
        )}

      </div>
    </div>
  );
};

export default HelpDetail;