use bevy::{app::AppExit, prelude::*};
use bevy_scriptum::prelude::*;
use bevy_scriptum::runtimes::ruby::prelude::*;
use magnus::TryConvert;
use magnus::value::InnerValue;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, startup)
        .add_systems(Update, call_lua_on_update_from_rust)
        .add_scripting::<RubyRuntime>(|runtime| {
            runtime.add_function(String::from("quit"), |mut exit: MessageWriter<AppExit>| {
                exit.write(AppExit::Success);
            });
        })
        .run();
}

fn startup(mut commands: Commands, assets_server: Res<AssetServer>) {
    commands.spawn(Script::<RubyScript>::new(
        assets_server.load("examples/ruby/function_return_value.rb"),
    ));
}

fn call_lua_on_update_from_rust(
    mut scripted_entities: Query<(Entity, &mut RubyScriptData)>,
    scripting_runtime: ResMut<RubyRuntime>,
    mut exit: MessageWriter<AppExit>,
) {
    for (entity, mut script_data) in &mut scripted_entities {
        let val = scripting_runtime
            .call_fn("get_value", &mut script_data, entity, ())
            .unwrap()
            .0;
        scripting_runtime.with_engine(|ruby| {
            let val: i32 = TryConvert::try_convert(val.get_inner_with(ruby)).unwrap();
            println!("script returned: {}", val);
        });
        exit.write(AppExit::Success);
    }
}
