use ruin_app::prelude::*;

#[derive(Clone)]
struct Project {
    id: u64,
    name: &'static str,
    status: &'static str,
    summary: &'static str,
}

#[ruin_runtime::async_main]
async fn main() -> ruin_app::Result<()> {
    App::new()
        .window(
            Window::new()
                .title("RUIN Children and Slots")
                .app_id("dev.ruin.children-and-slots")
                .size(1180.0, 820.0),
        )
        .mount(view! {
            ChildrenAndSlotsExample() {}
        })
        .run()
        .await
}

#[component]
fn ChildrenAndSlotsExample() -> impl IntoView {
    let active_project = use_signal(|| 1_u64);
    let dialog_open = use_signal(|| false);
    let projects = [
        Project {
            id: 1,
            name: "Renderer clip recovery",
            status: "Ready for validation",
            summary: "Nested clip propagation now preserves empty intersections all the way down the tree.",
        },
        Project {
            id: 2,
            name: "Runtime I/O dashboard",
            status: "Shipped",
            summary: "Filesystem snapshots and local TCP-backed endpoint previews now update immediately after async work completes.",
        },
        Project {
            id: 3,
            name: "Children contract support",
            status: "In progress",
            summary: "Custom components can now accept unnamed child content and typed child-like slot props without faking overlay APIs.",
        },
    ];
    let active = projects
        .iter()
        .find(|project| project.id == active_project.get())
        .cloned()
        .unwrap_or_else(|| projects[0].clone());

    view! {
        column(gap = 18.0, padding = 22.0, background = surfaces::canvas()) {
            text(role = TextRole::Heading(1), size = 30.0, weight = FontWeight::Semibold) {
                "Children and slots"
            }

            text(color = colors::muted(), wrap = TextWrap::Word) {
                "This honest slice implements unnamed child contracts plus typed child-like slot props. It does not pretend modal overlays or keyed list primitives exist yet; the dialog below is rendered inline on purpose."
            }

            SplitLayout(
                sidebar = vec![
                    view! {
                        text(role = TextRole::Heading(2), size = 22.0, weight = FontWeight::Semibold) {
                            "Views"
                        }
                    },
                    IntoView::into_view(FilterChip::builder().selected(active.id == 1).children("Rendering")),
                    IntoView::into_view(FilterChip::builder().selected(active.id == 2).children("Runtime I/O")),
                    IntoView::into_view(FilterChip::builder().selected(active.id == 3).children("Framework")),
                    view! {
                        text(color = colors::muted(), wrap = TextWrap::Word) {
                            "The sidebar itself is passed as a typed child-view slot, while the chips use a text-only child contract."
                        }
                    },
                ]
            ) {
                column(gap = 16.0) {
                    CardFrame(
                        title = view! {
                            text(role = TextRole::Heading(2), size = 24.0, weight = FontWeight::Semibold) {
                                "Workspace focus"
                            }
                        },
                        toolbar = vec![
                            view! {
                                button(on_press = {
                                    let dialog_open = dialog_open.clone();
                                    move |_| {
                                        let _ = dialog_open.set(true);
                                    }
                                }) { "Open review dialog" }
                            },
                            view! {
                                button(on_press = {
                                    let active_project = active_project.clone();
                                    move |_| {
                                        let next = if active_project.get() == 3 { 1 } else { active_project.get() + 1 };
                                        let _ = active_project.set(next);
                                    }
                                }) { "Cycle project" }
                            },
                        ]
                    ) {
                        text(color = colors::muted()) {
                            ("Active project: ", active.name)
                        }

                        text(color = colors::muted(), wrap = TextWrap::Word) {
                            active.summary
                        }

                        column(gap = 10.0) {
                            button(on_press = {
                                let active_project = active_project.clone();
                                move |_| {
                                    let _ = active_project.set(1);
                                }
                            }) { "Show rendering work" }

                            button(on_press = {
                                let active_project = active_project.clone();
                                move |_| {
                                    let _ = active_project.set(2);
                                }
                            }) { "Show runtime I/O work" }

                            button(on_press = {
                                let active_project = active_project.clone();
                                move |_| {
                                    let _ = active_project.set(3);
                                }
                            }) { "Show framework work" }
                        }
                    }

                    InlineDialog(
                        open = dialog_open.get(),
                        title = view! {
                            text(role = TextRole::Heading(2), size = 22.0, weight = FontWeight::Semibold) {
                                "Inline review dialog"
                            }
                        },
                        actions = vec![
                            view! {
                                button(on_press = {
                                    let dialog_open = dialog_open.clone();
                                    move |_| {
                                        let _ = dialog_open.set(false);
                                    }
                                }) { "Dismiss" }
                            },
                            view! {
                                button(on_press = {
                                    let dialog_open = dialog_open.clone();
                                    move |_| {
                                        eprintln!("example07: accepted review for {}", active.name);
                                        let _ = dialog_open.set(false);
                                    }
                                }) { "Accept" }
                            },
                        ]
                    ) {
                        text(color = colors::muted(), wrap = TextWrap::Word) {
                            "This body arrives through the unnamed child contract. The title and action row are separate typed slot props."
                        }

                        text(color = colors::muted()) {
                            ("Selected item status: ", active.status)
                        }
                    }
                }
            }
        }
    }
}

#[component]
fn SplitLayout(sidebar: ChildViews, children: ChildViews) -> impl IntoView {
    view! {
        row(gap = 18.0) {
            block(
                width = 280.0,
                gap = 12.0,
                padding = 16.0,
                background = surfaces::raised(),
                border_radius = 16.0,
            ) {
                sidebar
            }

            block(
                flex = 1.0,
                gap = 16.0,
                padding = 16.0,
                background = surfaces::raised(),
                border_radius = 16.0,
            ) {
                children
            }
        }
    }
}

#[component]
fn FilterChip(selected: bool, children: TextValue) -> impl IntoView {
    let background = if selected {
        surfaces::interactive()
    } else {
        surfaces::interactive_muted()
    };
    let border = if selected {
        colors::text()
    } else {
        colors::muted()
    };

    view! {
        block(
            padding = Edges::symmetric(14.0, 10.0),
            background = background,
            border = (1.0, border),
            border_radius = 999.0,
        ) {
            text(weight = FontWeight::Medium) {
                children
            }
        }
    }
}

#[component]
fn CardFrame(title: View, toolbar: ChildViews, children: ChildViews) -> impl IntoView {
    let header = view! {
        row(gap = 12.0) {
            block(flex = 1.0) {
                title
            }

            row(gap = 10.0) {
                toolbar
            }
        }
    };
    let mut body = vec![header];
    body.extend(children.into_vec());
    block()
        .gap(14.0)
        .padding(18.0)
        .background(surfaces::canvas())
        .border_radius(16.0)
        .children(body)
}

#[component]
fn InlineDialog(
    open: bool,
    title: View,
    actions: ChildViews,
    children: ChildViews,
) -> impl IntoView {
    if open {
        let actions_row = view! {
            row(gap = 10.0) {
                actions
            }
        };
        let mut body = vec![title];
        body.extend(children.into_vec());
        body.push(actions_row);
        block()
            .gap(14.0)
            .padding(18.0)
            .background(surfaces::raised())
            .border((1.0, colors::text()))
            .border_radius(16.0)
            .children(body)
    } else {
        column().children(())
    }
}
