//! Aspirational RUIN app API for typed children, slots, and builder finalization.
//!
//! Intentionally non-compiling; this is a design sketch.

use ruin::prelude::*;

#[ruin_runtime::async_main]
async fn main() -> ruin::Result<()> {
    App::new()
        .window(Window::new().title("RUIN Children Contracts").size(1100.0, 760.0))
        .mount::<ChildrenContractsExample>()
        .run()
        .await
}

#[component]
fn ChildrenContractsExample() -> impl View {
    let projects = projects();

    view! {
        column(fill = true, gap = 20, padding = 24) {
            text(role = TextRole::Heading(1), size = 30, weight = FontWeight::Semibold) {
                "Typed children and slots"
            }

            text(color = colors::muted()) {
                "This sketch focuses on declaration-side child contracts. The `view!` syntax stays \
                 uniform for all components, while the generated builder enforces props first and \
                 `children` as the finalizing step."
            }

            SplitLayout(sidebar = view! {
                block(gap = 12, width = 280) {
                    text(role = TextRole::Heading(2), size = 22, weight = FontWeight::Semibold) {
                        "Filters"
                    }
                    FilterChip(selected = true) { "All projects" }
                    FilterChip(selected = false) { "Recent" }
                }
            }) {
                column(gap = 12) {
                    text(role = TextRole::Heading(2), size = 22, weight = FontWeight::Semibold) {
                        "Projects"
                    }

                    ForEach(items = projects, key = |project| project.id) { |project| 
                        ProjectRow(project = project.clone()) {}
                    }
                }
            }

            Dialog(
                open = true,
                title = view! {
                    text(role = TextRole::Heading(2), size = 22, weight = FontWeight::Semibold) {
                        "Dialog with custom title and actions"
                    }
                },
                actions = view! {
                    button(kind = ButtonKind::Secondary) { "Cancel" }
                    button(kind = ButtonKind::Primary) { "Delete" }
                },
            ) {
                text(color = colors::muted()) {
                    "A dialog can declare exactly one main child body plus separately typed \
                     title/actions slots."
                }
            }
        }
    }
}

#[component]
fn FilterChip(children: impl InlineChildren, selected: bool) -> impl View {
    let background = if selected {
        colors::accent()
    } else {
        colors::muted().with_alpha(0.12)
    };

    view! {
        block(
            padding = (8, 16),
            background = background,
            corner_radius = 1000,
        ) {
            children
        }
    }
}

#[component]
fn ForEach<T, C>(
    items: impl IntoIterator<Item = T>,
    key: impl Fn(&T) -> u64,
    children: impl Fn(T) -> C,
) -> impl View
where
    C: Children,
{
    todo!("The framework would lower this into a keyed mapper primitive or composite")
}

#[derive(Clone)]
struct Project {
    id: u64,
    name: String,
}

fn projects() -> Vec<Project> {
    Vec::new()
}
