use leptos::prelude::*;

/// Toast overlay — SSR returns `()` (zero DOM nodes, zero hydration-cursor
/// impact). WASM mounts the reactive container to `document.body` via a fresh
/// Leptos root that is completely outside the server-hydrated component tree,
/// so DynChild boundary markers from `<Show>` / `<For>` never appear in the SSR
/// HTML and the hydration cursor is never disturbed.
#[component]
pub fn ToastContainer() -> impl IntoView {
    #[cfg(target_arch = "wasm32")]
    {
        use super::{ToastKind, ToastNotification};

        let toasts = use_context::<RwSignal<Vec<ToastNotification>>>()
            .unwrap_or_else(|| RwSignal::new(vec![]));

        // No reactive reads inside this closure → runs exactly once after hydration.
        // mount_to_body creates a new Owner so the reactive tree is independent of
        // the hydrated app tree. forget() keeps the MountHandle alive for the
        // application's lifetime.
        Effect::new(move |_| {
            leptos::mount::mount_to_body(move || {
                view! {
                    <div class="fixed bottom-4 right-4 z-50 flex flex-col gap-2 pointer-events-none">
                        <Show when=move || !toasts.get().is_empty()>
                            <For
                                each=move || toasts.get()
                                key=|t| t.id
                                let:toast
                            >
                                {
                                    let base = "pointer-events-auto px-4 py-3 rounded-lg shadow-lg text-sm font-medium max-w-sm transition-all";
                                    let color = match &toast.kind {
                                        ToastKind::Error   => "bg-red-600 text-white",
                                        ToastKind::Warning => "bg-amber-500 text-white",
                                        ToastKind::Info    => "bg-blue-600 text-white",
                                    };
                                    let msg = toast.message.clone();
                                    let id  = toast.id;
                                    view! {
                                        <div class=format!("{base} {color}")>
                                            <div class="flex items-start gap-2">
                                                <span class="flex-1">{msg}</span>
                                                <button
                                                    class="ml-2 opacity-70 hover:opacity-100 shrink-0"
                                                    on:click=move |_| toasts.update(|v| v.retain(|t| t.id != id))
                                                >
                                                    "×"
                                                </button>
                                            </div>
                                        </div>
                                    }
                                }
                            </For>
                        </Show>
                    </div>
                }
            });
        });
    }
}
