import React from "react";
import style from "./postList.module.css";
import SelfStatus from "@/components/selfStatus/selfStatus";
import Navbar from "@/components/navbar/navbar";
import PostsPanel from "@/components/postsPanel/postsPanel";
import { getPosts, unknownAPI } from "@/api/post";
import { Form } from "antd"
import { useApi } from "@/hooks/request";
import request from "@/utils/request";
import { Pagination, PaginationProps } from "antd";
import { set } from "lodash";
import { useEffect } from "react";
import { useNavigate, useSearchParams } from "react-router";


const PostList:React.FC = () => {
    const [searchParams] = useSearchParams();
    const type = searchParams.get("type") || ""; 
    const nav = useNavigate();

    if(type in ['video', 'music', 'game', 'software']) {
        nav('/')
    }

    const {data:postList, refresh:getPostList} = useApi(() => request.get(getPosts + `?tags=${[type]}&page=${currentPage}&pageSize=${pageSize}`), false);
    const [currentPage, setCurrentPage] = React.useState(1);
    const [pageSize, setPageSize] = React.useState(10);
    const handlePageChange = (page:number, size?:number) => {
        setCurrentPage(page);
        if(size) setPageSize(size);
        console.log(page, size);
    };

    const handlePostClick = (postId:number) => {
        nav(`/postsDetail?postId=${postId}`);
    }

    useEffect(() => {
        getPostList();
    },[currentPage, pageSize]);

    return (
        <div className={style.container}>
            <div className={style.left}>
                <div className={style.navbar}>
                    <Navbar current={type}/>
                </div>
                <div className={style.content}>
                    {postList && postList.length > 0 ? (
                        postList.map((post: { postId: number; postTitle: string; postContent: string; createdAt:string }) => (
                            <div key={post.postId} className={style.contentItem} onClick={() => handlePostClick(post.postId)}>
                                <h3>{post.postTitle}</h3>
                                <p>{post.postContent.substring(0, 20)}</p>
                                <p className={style.createDate}>{post.createdAt}</p>
                            </div>
                        ))
                    ) : (
                        <div className={style.noData}>未查询到相关帖子</div>
                    )}

                    <Pagination
                        showSizeChanger
                        onShowSizeChange={handlePageChange}
                        defaultCurrent={1}
                        total={500}
                        onChange={handlePageChange}
                    />
                </div>
            </div>
            <div className={style.right}>
                <div className={style.selfStatus}>
                    <SelfStatus/>
                </div>
                <div className={style.filter}>
                    
                </div> 
            </div>
        </div>
    )
}

export default PostList;