import React, { useState, useEffect, useRef } from 'react';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import { 
  getHelpPostDetail,
  addHelpPostComment,
  likeHelpPost,
  deleteHelpPost
} from '../api/helpPost';
import {
  likeHelpPostComment,
  getCommentReplies,
  addHelpCommentReply,
  deleteHelpComment
} 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 getHelpPostDetail(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 likeHelpPost(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 deleteHelpPost(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 formData = new FormData();
        formData.append('content', newComment);
        formData.append('authorId', username);
        if (commentImage) {
          formData.append('image', commentImage);
        }

        const response = await addHelpPostComment(id, formData);
    
        // 修改这里的响应处理逻辑
        if (response.data && response.data.code === 200) {
          await fetchPostDetail();
          
          setNewComment('');
          setCommentImage(null); // 清空评论图片
        } else {
          setError(response.data.message || '评论失败');
        }
      } catch (err) {
        setError('评论失败: ' + (err.response?.data?.message || err.message));
      }
    };
    
    
    const handleLikeComment = async (commentId) => {
      try {
        await likeHelpPostComment(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 deleteHelpComment(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 addHelpCommentReply(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;