//! 文章详情页面模块。
//!
//! 对应路由 `/post/:slug`。
//!
//! 数据获取：通过 `use_server_future` 调用 `get_post_by_slug` server function，
//! 根据 URL 中的 slug 获取单篇文章详情（含正文 HTML、目录、封面及上下篇导航）。
//! 路由参数 slug 变化时，Dioxus 会自动重跑该 future，无需镜像成 signal 再手动同步。
//! 在 `wasm32` 目标下，server function 的函数体被替换为向服务端端点发起 HTTP POST 请求的客户端存根；
//! 实际的数据库访问逻辑仅在 `feature = "server"` 启用时运行。

use dioxus::prelude::*;
use dioxus::router::components::Link;

use crate::api::posts::{get_post_by_slug, SinglePostResponse};
use crate::components::post::post_content::PostContent;
use crate::components::post::post_cover::PostCover;
use crate::components::post::post_footer::PostFooter;
use crate::components::post::post_header::PostHeader;
use crate::components::post::post_toc::PostToc;
use crate::components::skeletons::delayed_skeleton::DelayedSkeleton;
use crate::components::skeletons::post_detail_skeleton::PostDetailSkeleton;
use crate::router::Route;

/// 文章详情页面组件，对应路由 `/post/:slug`。
///
/// 根据 slug 异步获取文章，渲染文章头部、封面、目录、正文、页脚及评论区；
/// 若文章不存在或加载失败，则展示对应的提示页面。
#[component]
pub fn PostDetail(slug: String) -> Element {
    // 直接读取 slug prop：路由参数变化时 Dioxus 会自动重跑该 server future，
    // 无需镜像成 signal 再手动 set（render 期 set signal 是 Dioxus 反模式）。
    let post = use_server_future(move || get_post_by_slug(slug.clone()))?;

    // 将结果映射为更直观的 Ok(post) / Err("not_found") / Err("error") 三种状态。
    let post_data = post.read().as_ref().map(|r| match r {
        Ok(SinglePostResponse { post: Some(post) }) => Ok(post.clone()),
        Ok(SinglePostResponse { post: None }) => Err("not_found"),
        Err(_) => Err("error"),
    });

    match post_data {
        Some(Ok(post)) => {
            rsx! {
                article { class: "post-single", key: "{post.slug}",
                    PostHeader { post: post.clone() }

                    // 如果文章设置了封面图，则渲染封面组件。
                    if let Some(cover) = &post.cover_image {
                        PostCover { src: cover.clone() }
                    }

                    // 如果文章生成了目录 HTML，则渲染目录组件。
                    if let Some(toc) = &post.toc_html {
                        PostToc { toc_html: toc.clone() }
                    }

                    PostContent { content_html: post.content_html.clone().unwrap_or_default() }

                    PostFooter { post: post.clone() }

                    // 仅对已发布文章展示评论区域，使用 SuspenseBoundary 处理加载状态。
                    if post.status == crate::models::post::PostStatus::Published {
                        div { class: "mt-12 border-t border-gray-200 dark:border-[#333] pt-8",
                            SuspenseBoundary {
                                fallback: move |_| rsx! {
                                    crate::components::skeletons::comment_skeleton::CommentListSkeleton {}
                                },
                                crate::components::comments::section::CommentSection { post_id: post.id }
                            }
                        }
                    }
                }
            }
        }
        Some(Err("not_found")) => {
            rsx! {
                div { class: "text-center py-20",
                    h2 { class: "text-2xl font-bold text-paper-primary mb-4", "文章不存在" }
                    p { class: "text-paper-secondary mb-6",
                        "这篇文章可能已被删除或移动。"
                    }
                    Link {
                        class: "px-6 py-2 bg-paper-primary text-paper-theme rounded-full font-medium hover:opacity-80 transition-opacity",
                        to: Route::Home {},
                        "返回首页"
                    }
                }
            }
        }
        Some(Err("error")) => {
            rsx! {
                div { class: "text-center text-red-500 dark:text-red-400 py-20", "加载失败" }
            }
        }
        _ => {
            rsx! {
                DelayedSkeleton { PostDetailSkeleton {} }
            }
        }
    }
}
