'use client';

import React, { useEffect, useState, useRef } from 'react';
import { Image } from 'primereact/image';
import { Avatar } from 'primereact/avatar';
import { Button } from 'primereact/button';
import { InputText } from "primereact/inputtext";
// 页面跳转
import { useParams } from 'next/navigation'
// 接口传输
import axios from 'axios';
// 回复评论
import { OverlayPanel } from 'primereact/overlaypanel';
import { Sidebar } from 'primereact/sidebar';
// 分页
import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
// 消息提醒
import { Toast } from 'primereact/toast';
import { useLocalStorage } from '../../../hook/useLocalStorage';
// 样式
import './thread.scss';
interface User {
    Id: number;
}


// 评论信息
interface Comment {
    commentId: number;
    userId: number | null;
    replyId: number;
    content: string;
    createdAt: string;
}
// 评论列表
interface CommentList {
    records: Comment[];      // 当前页评论数组
}
// 帖子信息
interface ThreadInfo {
    threadId: number;
    userId: number;
    threadPicture: string;
    title: string;
    content: string;
    likes: number;
    isLike: boolean;
    createdAt: string;
    commentNumber: number;
    communityId: number;
}
// 用户信息
interface UserInfo {
    userId: number;
    username: string;
    avatar: string;
    signature: string;
}
// 新评论接口
interface NewComment {
    userId: number;
    threadId: number | null;
    resourceId: number | null;
    replyId: number | null;
    content: string;
    createdAt: string;
}


//帖子详情界面
export default function ThreadDetailPage() {
    const user = useLocalStorage<User>('user');
    const userId: number = user?.Id ?? -1;

    // 获取URL参数，页面跳转
    const params = useParams<{ threadId: string }>()
    const threadId = decodeURIComponent(params.threadId); // 防止中文路径乱码
    // 消息提醒
    const toast = useRef<Toast>(null);
    // 帖子信息
    const [threadInfo, setThreadInfo] = useState<ThreadInfo | null>(null);
    // 发帖人信息
    const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
    // 评论人信息
    const [commentUserInfos, setCommentUserInfos] = useState<Map<number, UserInfo>>(new Map());
    //评论
    const [comments, setComments] = useState<Comment[]>([]);
    const [commentValue, setCommentValue] = useState<string>('');
    const [totalComments, setTotalComments] = useState<number>(0);
    // 回复
    const [replyValue, setReplyValue] = useState<string>('');
    const [visibleReply, setVisibleReply] = useState<boolean>(false);// 回复评论可视
    // 评论选择框
    const ops = useRef<OverlayPanel[]>([]);

    // 分页
    const [first, setFirst] = useState<number>(0);
    const [rows, setRows] = useState<number>(5);
    const onPageChange = (event: PaginatorPageChangeEvent) => {
        setFirst(event.first);
        setRows(event.rows);
    };

    // 获取帖子信息
    useEffect(() => {
        fetchThreadInfo();
    }, [threadId, threadInfo]);

    const fetchThreadInfo = async () => {
        try {
            const { data } = await axios.get(process.env.PUBLIC_URL + `/thread`, {
                params: {
                    threadId,
                    userId
                }
            });
            setThreadInfo(data);
            setTotalComments(data.commentNumber);
        } catch (err) {
            console.error(err);
            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取帖子信息失败' });
        }
    };


    // 获取发帖人
    useEffect(() => {
        if (!threadInfo) return;
        // 发帖人
        axios.get(process.env.PUBLIC_URL + `/user/info?userId=${threadInfo.userId}`)
            .then(res => setUserInfo(res.data))
            .catch(console.error);
    }, [threadInfo]);

    // 处理点赞
    const handleLike = async () => {
        if (!threadInfo) return;
        if (!threadInfo.isLike) {
            try {
                const response = await axios.post(
                    process.env.PUBLIC_URL + `/thread/like`, {
                     threadId, userId
                }
                );
                fetchThreadInfo(); // 刷新帖子信息
                if (response.status === 200) {
                    console.log('点赞成功:', response.data);
                    toast.current?.show({ severity: 'success', summary: 'Success', detail: '点赞成功' });
                }
            } catch (error) {
                console.error('点赞失败:', error);
                toast.current?.show({ severity: 'error', summary: 'error', detail: '点赞失败' });
            }
        } else {
            try {
                const response = await axios.delete(
                    process.env.PUBLIC_URL + `/thread/like`, {
                    params: { threadId, userId }
                }
                );
                fetchThreadInfo(); // 刷新帖子信息
                if (response.status === 200) {
                    console.log('取消点赞成功:', response.data);
                    toast.current?.show({ severity: 'success', summary: 'Success', detail: '取消点赞成功' });
                }
            } catch (error) {
                console.error('取消点赞失败:', error);
                toast.current?.show({ severity: 'error', summary: 'error', detail: '取消点赞失败' });
            }
        }

    };


    // 当 threadId 或分页参数变化时重新拉评论
    useEffect(() => {
        if (!threadId) return;

        fetchComments();
    }, [threadId, first, rows]);


    //通过评论ID获取评论人信息
    const getReplyUserName = (replyId: number) => {
        if (replyId == null || replyId == 0) return '';
        const replyComment = comments.find(comment => comment.commentId === replyId);
        if (!replyComment?.userId) return '匿名用户';
        return "回复 " + commentUserInfos.get(replyComment.userId)?.username || '匿名用户';
    };

    // 获取评论列表
    const fetchComments = async () => {
        try {
            const pageNumber = first / rows + 1;
            console.log("当前页" + pageNumber + "size" + rows);
            const response = await axios.get<CommentList>(
                process.env.PUBLIC_URL + `/comment`, {
                params: { threadId, pageNumber, rows }
            }
            );
            console.log('获取评论列表:', response.data.records);
            setComments(response.data.records);
            // 拉取评论对应用户信息
            response.data.records.forEach(comment => {
                if (comment.userId != null && !commentUserInfos.has(comment.userId)) {
                    axios.get<UserInfo>(
                        process.env.PUBLIC_URL + `/user/info`,
                        { params: { userId: comment.userId } }
                    ).then(res => {
                        setCommentUserInfos(prev => new Map(prev).set(comment.userId!, res.data));
                    });
                }
            });
        } catch (err) {
            console.error('获取评论失败', err);
            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取评论失败' });
        }
    };

    // 回复评论接口
    const publishReply = async (commentId: number) => {
        if (!replyValue.trim() || !threadInfo) return;
        console.log('发布评论:', commentId);
        try {
            const newComment: NewComment = {
                userId,
                threadId: threadInfo.threadId,
                resourceId: null,
                replyId: commentId,
                content: commentValue,
                createdAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
            };

            const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);

            if (response.status === 200) {
                toast.current?.show({ severity: 'success', summary: 'Success', detail: '回复成功' });
                // 更新评论列表
                fetchComments();
                setVisibleReply(false)
                // 清空输入框
                setReplyValue('');
            }
        } catch (error) {
            console.error('发布评论失败:', error);
            toast.current?.show({ severity: 'error', summary: 'error', detail: '回复失败' });
        }
    };

    // 发布评论接口
    const publishComment = async () => {
        if (!commentValue.trim() || !threadInfo) return;

        try {
            const newComment: NewComment = {
                userId,
                threadId: threadInfo.threadId,
                resourceId: null,
                replyId: null, // 直接评论，不是回复
                content: commentValue,
                createdAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
            };

            const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);

            if (response.status === 200) {
                toast.current?.show({ severity: 'success', summary: 'Success', detail: '评论成功' });
                // 更新评论列表
                fetchComments();
                // 清空输入框
                setCommentValue('');
            }
        } catch (error) {
            console.error('发布评论失败:', error);
            toast.current?.show({ severity: 'error', summary: 'error', detail: '发布评论失败' });
        }
    };

    // 删除评论接口
    const deleteComment = async (commentId: number) => {
        if (!threadInfo) return;

        try {
            // 调用 DELETE 接口，URL 中最后一段是要删除的 commentId
            const response = await axios.delete(
                process.env.PUBLIC_URL + `/comment?commentId=${commentId}`
            );

            if (response.status === 200) {
                fetchComments();
                toast.current?.show({ severity: 'success', summary: 'Success', detail: '删除评论成功' });
            } else {
                toast.current?.show({ severity: 'error', summary: 'error', detail: '删除评论失败' });
                console.error('删除评论失败，状态码：', response.status);
            }
        } catch (error) {
            console.error('删除评论接口报错:', error);
        }
    };

    const ReplyHeader = (
        <div className="flex align-items-center gap-1">
            <h3>回复评论</h3>
        </div>
    );
    if (!threadInfo || !userInfo) return <div>Loading...</div>;
    return (
        <div className="thread-detail">
            <Toast ref={toast}></Toast>
            {/* 帖子头部 */}
            <div className="thread-header">
                <div className="user-info">
                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                    <div className="user-meta">
                        <h3>{userInfo.username}</h3>
                        <span>{userInfo.signature}</span>
                    </div>
                </div>
                <span className="post-time">{threadInfo.createdAt}</span>
            </div>

            {/* 帖子内容 */}
            <div className="thread-content">
                <h1>{threadInfo.title}</h1>
                <div className="content-body">
                    <Image
                        src={ threadInfo.threadPicture}
                        alt={threadInfo.title}
                        width="800"
                        height="400"
                        className="thread-image"
                    />
                    <p>{threadInfo.content}</p>
                </div>
                <div className="thread-actions">
                    <Button
                        icon={"pi pi-face-smile"}
                        onClick={handleLike}
                        className={`like-button ${threadInfo.isLike ? 'liked' : ''}`}
                        label={threadInfo.likes.toString()}
                    />
                </div>
            </div>
            {/* 评论列表 */}
            <div className="comments-section">
                <div className="comments-header">
                    <h2>评论 ({totalComments})</h2>
                </div>
                <div className="comments-input">
                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                    <InputText value={commentValue} placeholder="发布你的评论" onChange={(e) => setCommentValue(e.target.value)} />
                    <Button label="发布评论" onClick={publishComment} disabled={!commentValue.trim()} />
                </div>
                <div className="comments-list">
                    {comments.map((comment, index) => (
                        <div key={comment.commentId} className="comment-item">
                            <div className="comment-user">
                                <Avatar
                                    image={comment.userId ?  "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
                                    size="normal"
                                    shape="circle"
                                />
                                <div className="comment-meta">
                                    <span className="username">
                                        {comment.userId ? commentUserInfos.get(comment.userId)?.username : '匿名用户'}
                                    </span>
                                    <div className="comment-time">
                                        <span className="floor">#{index + 1}楼</span>
                                        <span className="time">{comment.createdAt}</span>
                                    </div>
                                </div>
                                <i className='pi pi-ellipsis-v' onClick={(e) => ops.current[index].toggle(e)} />
                            </div>
                            <div className="comment-content">
                                {<span className="reply-to">{getReplyUserName(comment.replyId)}</span>}
                                <p>{comment.content}</p>
                            </div>
                            <OverlayPanel       // 回调 ref：把实例放到 ops.current 对应的位置
                                ref={el => {
                                    if (el) ops.current[index] = el;
                                }}>
                                <Button label="回复" text size="small" onClick={() => setVisibleReply(true)} />
                                {comment.userId === userId &&
                                    <Button
                                        label="删除"
                                        text
                                        size="small"
                                        onClick={() => { console.log('Deleting comment:', comment.commentId, 'by user:', comment.userId); deleteComment(comment.commentId) }}
                                    />
                                }
                            </OverlayPanel>
                            <Sidebar className='reply' header={ReplyHeader} visible={visibleReply} position="bottom" onHide={() => setVisibleReply(false)}>
                                <div className="reply-input">
                                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                                    <InputText value={replyValue} placeholder="发布你的评论" onChange={(e) => setReplyValue(e.target.value)} />
                                    <Button label="发布评论" onClick={() => publishReply(comment.commentId)} disabled={!replyValue.trim()} />
                                </div>
                            </Sidebar>
                        </div>
                    ))}
                    {totalComments > 5 && (<Paginator className="Paginator" first={first} rows={rows} totalRecords={totalComments} rowsPerPageOptions={[5, 10]} onPageChange={onPageChange} />)}
                </div>
            </div>
        </div>
    );
}