//! Aspirational RUIN app API for runtime-integrated filesystem and network I/O.
//!
//! 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 Runtime I/O").size(1280.0, 820.0))
        .mount::<RuntimeIoExample>()
        .run()
        .await
}

#[component]
fn RuntimeIoExample() -> impl View {
    let manifest_path = use_signal(|| "./Cargo.toml".to_string());
    let release_url =
        use_signal(|| "https://api.github.com/repos/wtemple/ruin/releases/latest".to_string());

    let manifest = use_resource(move || {
        let path = manifest_path.get();
        async move { ruin_runtime::fs::read_to_string(path).await }
    });

    let release = use_resource(move || {
        let url = release_url.get();
        async move { ruin_http::get_json::<ReleaseSummary>(&url).await }
    });

    let save_snapshot = use_action(move |_| {
        let manifest = manifest.latest_cloned();
        async move {
            let manifest = manifest.ok_or_else(|| anyhow!("manifest is not loaded yet"))?;
            ruin_runtime::fs::write("./tmp/manifest-snapshot.toml", manifest).await?;
            Ok::<_, anyhow::Error>(())
        }
    });

    use_async_effect(move || {
        let url = release_url.get();
        async move {
            tracing::info!(%url, "release endpoint changed");
            Ok::<_, anyhow::Error>(())
        }
    });

    view! {
        row(fill = true, gap = 20, padding = 20) {
            block(fill = true, gap = 12) {
                text(role = TextRole::Heading(1), size = 26, weight = FontWeight::Semibold) {
                    "Filesystem"
                }
                text_input(value = manifest_path, placeholder = "./Cargo.toml") {}

                match manifest.read() {
                    Pending => view! { ProgressSpinner(label = "Reading file...") {} },
                    Ready(Ok(contents)) => view! {
                        column(gap = 12) {
                            button(
                                on_press = save_snapshot.dispatcher(),
                                disabled = save_snapshot.pending(),
                            ) {
                                "Save snapshot"
                            }

                            CodeBlock(language = "toml") { contents }
                        }
                    },
                    Ready(Err(error)) => view! {
                        ErrorPanel(title = "Failed to read file", detail = error.to_string()) {}
                    },
                }
            }

            block(fill = true, gap = 12) {
                text(role = TextRole::Heading(1), size = 26, weight = FontWeight::Semibold) {
                    "Network"
                }
                text_input(value = release_url, placeholder = "https://...") {}

                match release.read() {
                    Pending => view! { ProgressSpinner(label = "Fetching release summary...") {} },
                    Ready(Ok(release)) => view! {
                        column(gap = 8) {
                            text(size = 20, weight = FontWeight::Semibold) { release.name.clone() }
                            text(color = colors::muted()) { release.published_at.clone() }
                            text { release.notes.clone() }
                        }
                    },
                    Ready(Err(error)) => view! {
                        ErrorPanel(title = "Failed to fetch release", detail = error.to_string()) {}
                    },
                }
            }
        }
    }
}

struct ReleaseSummary {
    name: String,
    published_at: String,
    notes: String,
}
