'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 { useRouter } 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 './thread.scss';


// 评论信息
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;
    resourceId: number;
    replyId: number;
    content: string;
    createdAt: string;
}


//帖子详情界面
export default function ThreadDetailPage() {
    // 获取URL参数，页面跳转
    const params = useParams<{ threadId: string }>()
    const threadId = decodeURIComponent(params.threadId); // 防止中文路径乱码
    const router = useRouter();
    // 消息提醒
    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(`http://127.0.0.1:4523/m1/6387307-6083949-default/thread?threadId=${threadId}`);
            setThreadInfo(data);
            setTotalComments(data.commentNumber);
        } catch (err) {
            console.error(err);
            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取帖子信息失败' });
        }
    };

    // 获取发帖人
    useEffect(() => {
        if (!threadInfo) return;
        // 发帖人
        axios.get(`http://127.0.0.1:4523/m1/6387307-6083949-default/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(
                    `http://127.0.0.1:4523/m1/6387307-6083949-default/thread/like`, {
                    params: { threadId, userId: 22301145 }
                }
                );
                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(
                    `http://127.0.0.1:4523/m1/6387307-6083949-default/thread/like`, {
                    params: { threadId, userId: 22301145 }
                }
                );
                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 page = first / rows + 1;
            console.log("当前页" + page + "size" + rows);
            const response = await axios.get<CommentList>(
                `http://127.0.0.1:4523/m1/6387307-6083949-default/comments`, {
                params: { threadId, page, 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>(
                        `http://127.0.0.1:4523/m1/6387307-6083949-default/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: 22301145,
                threadId: threadInfo.threadId,
                resourceId: 0,
                replyId: commentId,
                content: commentValue,
                createdAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
            };

            const response = await axios.post('http://127.0.0.1:4523/m1/6387307-6083949-default/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: 22301145,
                threadId: threadInfo.threadId,
                resourceId: 0,
                replyId: 0, // 直接评论，不是回复
                content: commentValue,
                createdAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
            };

            const response = await axios.post('http://127.0.0.1:4523/m1/6387307-6083949-default/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(
                `http://127.0.0.1:4523/m1/6387307-6083949-default/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={process.env.NEXT_PUBLIC_NGINX_URL + "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={process.env.NEXT_PUBLIC_NGINX_URL + 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>
                    <Button label="返回社区" link onClick={() => router.push(`/community/community-detail/${threadInfo.communityId}`)} />
                </div>
                <div className="comments-input">
                    <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "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 ? process.env.NEXT_PUBLIC_NGINX_URL + "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 === 22301145 &&
                                    <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={process.env.NEXT_PUBLIC_NGINX_URL + "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>
    );
}