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}>
        返回求助区
      </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;