use crate::prelude::*;

pub(crate) struct LoadingPlugin;

impl Plugin for LoadingPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Startup, initialize)
            .add_systems(Update, loading.run_if(in_state(GameState::Loading)))
            .add_systems(
                OnEnter(GameState::Loading),
                (activate::<Loading>, enter_loading),
            )
            .add_systems(
                OnExit(GameState::Loading),
                (deactivate::<Loading>, exit_loading),
            );
    }
}

#[derive(Debug, Component)]
struct Loading;

// TODO: Why is this image not showing??
fn initialize(mut commands: Commands, server: Res<AssetServer>) {
    commands.spawn((
        Loading,
        Camera2dBundle { ..default() },
        UiCameraConfig { show_ui: true },
    ));
    commands.spawn((
        Loading,
        ImageBundle {
            image: UiImage {
                texture: server.load("images/Liquid Mirror.jpg"),
                ..default()
            },
            style: Style {
                width: Val::Percent(100.0),
                height: Val::Percent(100.0),
                ..default()
            },
            visibility: Visibility::Hidden,
            ..default()
        },
    ));
}

/// On enter loading, activate camera
fn enter_loading(mut cameras: Query<&mut Camera, With<Loading>>) {
    cameras
        .iter_mut()
        .for_each(|mut camera| camera.is_active = true);
}

/// On exit loading, deactivate camera
/// This used to be general purpose, but we got rid of the 2d display mode, so it is hard coded for loading -> main game
fn exit_loading(mut cameras: Query<&mut Camera, With<Loading>>) {
    cameras
        .iter_mut()
        .for_each(|mut camera| camera.is_active = false);
}

fn loading(
    server: Res<AssetServer>,
    sprites: Res<Assets<Image>>,
    gltfs: Res<Assets<Gltf>>,
    tweaks: Res<Assets<tweak::Tweaks>>,
    fonts: Res<Assets<Font>>,
    mut next_state: ResMut<NextState<GameState>>,
) {
    let s = (!sprites.is_empty())
        && sprites
            .ids()
            .all(|id| server.is_loaded_with_dependencies(id));
    let g = (!gltfs.is_empty()) && gltfs.ids().all(|id| server.is_loaded_with_dependencies(id));
    let t = (!tweaks.is_empty())
        && tweaks
            .ids()
            .all(|id| server.is_loaded_with_dependencies(id));
    let f = (!fonts.is_empty()) && fonts.ids().all(|id| server.is_loaded_with_dependencies(id));

    debug!("s {} g {} t {} f {}", s, g, t, f);

    if t {
        next_state.set(GameState::Menu)
    }
}
