import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import styles from './PostDetail.module.css';
import { Card, List, Typography, Button, Input, Spin, Empty } from 'antd';
type CommentProps = {
	children?: React.ReactNode;
};
import { getPostDetail } from '@/api/post';
import { getPostComments } from '@/api/comment';
import { useSearchParams } from 'react-router-dom';
import request from '@/utils/request';
import { useApi } from '@/hooks/request';
import Navbar from '@/components/navbar/navbar';

const { Title, Text, Paragraph } = Typography;
const { TextArea } = Input;

export interface PostResponse {
	createdAt?: number;
	hotScore?: number;
	lastCalculated?: number;
	postContent?: string;
	postId?: number;
	postTitle?: string;
	postType?: string;
	userId?: number;
	viewCount?: number;
	[property: string]: any;
}

export interface CommentResponse {
	commentId?: number;
	content?: string;
	createdAt?: number;
	parentCommentId?: number | null;
	postId?: number;
	replies?: CommentResponse[];
	userId?: number;
	[property: string]: any;
}

const PostDetail: React.FC = () => {
	const [searchParams] = useSearchParams();
	const postId = searchParams.get('postId');
	const { refresh: getPostDetailRefresh } = useApi(() => request.get(getPostDetail + `/${postId}`), false);
	const { refresh: getPostCommentsRefresh } = useApi(() => request.get(getPostComments + `/${postId}`), false);
	const [post, setPost] = useState<PostResponse | null>(null);
	const [comments, setComments] = useState<CommentResponse[]>([]);
	const [newComment, setNewComment] = useState<string>('');
	const [loading, setLoading] = useState<boolean>(true);

	useEffect(() => {
		console.log('postId', postId);
		if (!postId) return;
		const fetchData = async () => {
			setLoading(true);
			const res = await getPostDetailRefresh();
			if (res == null || (res as any).error) {
				setLoading(false);
				return;
			}
			setPost(res as PostResponse);
			await getPostCommentsRefresh();
			setComments(res as CommentResponse[]);
			setLoading(false);
		};
		fetchData();
	}, [postId]);

	if (loading) return <div className={styles.center}><Spin /></div>;
	if (!post) return <div className={styles.center}><Empty description="未找到帖子" /></div>;

	return (
		<div className={styles.container}>
			<div className={styles.nav}>
				<Navbar current={post.postType} />
			</div>
			<div className={styles.content}>
				<div className={styles.postDetail}>
						
				</div >
				<Card title={post.postTitle} className={styles.card}>
					<Paragraph>{post.postContent}</Paragraph>
					<div className={styles.actions}>
						<Button type="primary" onClick={() => setNewComment('')}>评论</Button>
					</div>
				</Card>

				<List
					className={styles.commentList}
					header={<Title level={4}>评论区</Title>}
					dataSource={comments}
					renderItem={(item) => (
						<List.Item key={item.commentId}>
							<List.Item.Meta
								title={<Text strong>{item.userId}</Text>}
								description={<Text>{item.content}</Text>}
							/>
						</List.Item>
					)}
				/>

				<TextArea
					rows={4}
					value={newComment}
					onChange={(e) => setNewComment(e.target.value)}
					placeholder="写下你的评论..."
				/>
				</div>
		</div>
	);
};

export default PostDetail;