use bevy::{
    app::AppExit,
    input::{keyboard::KeyboardInput, ButtonState},
};

use crate::prelude::*;

pub(crate) struct MenuPlugin;

impl Plugin for MenuPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Startup, init_menu_ui)
            .add_systems(
                Update,
                (
                    handle_menu_button::<GameState>, // Run in all states
                    handle_menu_quit.run_if(in_state(GameState::Menu)),
                    bevy::window::close_on_esc.run_if(in_state(GameState::Menu)),
                ),
            )
            .add_systems(
                OnEnter(GameState::Menu),
                (activate::<Menu>, activate::<display3d::Display3d>),
            )
            .add_systems(OnExit(GameState::Menu), deactivate::<Menu>);
    }
}

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

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

fn init_menu_ui(mut commands: Commands) {
    commands
        .spawn((
            Menu,
            NodeBundle {
                style: Style {
                    width: Val::Percent(100.0),
                    height: Val::Percent(100.0),
                    justify_content: JustifyContent::Center,
                    align_items: AlignItems::Center,
                    flex_direction: FlexDirection::Column,
                    position_type: PositionType::Absolute,
                    ..default()
                },
                background_color: Color::NONE.into(),
                visibility: Visibility::Hidden,
                ..default()
            },
        ))
        .with_children(|parent| {
            parent.spawn(TextBundle::from_section(
                "M A R T I A N   C H E S S",
                TextStyle {
                    font_size: 48.0,
                    color: Color::ORANGE_RED,
                    ..default()
                },
            ));
            parent
                .spawn((
                    GameState::Intro,
                    ButtonBundle {
                        style: Style {
                            padding: UiRect::all(Val::Px(5.0)),
                            margin: UiRect::all(Val::Px(5.0)),
                            ..default()
                        },
                        background_color: Color::ORANGE.with_a(0.5).into(),
                        ..default()
                    },
                ))
                .with_children(|parent| {
                    parent.spawn((
                        GameState::Intro,
                        TextBundle::from_section(
                            "Start",
                            TextStyle {
                                color: Color::BLACK,
                                font_size: 32.0,
                                ..default()
                            },
                        ),
                    ));
                });

            parent
                .spawn((
                    GameState::Credits,
                    ButtonBundle {
                        style: Style {
                            padding: UiRect::all(Val::Px(5.0)),
                            margin: UiRect::all(Val::Px(5.0)),
                            ..default()
                        },
                        background_color: Color::ORANGE.with_a(0.5).into(),
                        ..default()
                    },
                ))
                .with_children(|parent| {
                    parent.spawn((
                        GameState::Credits,
                        TextBundle::from_section(
                            "Credits",
                            TextStyle {
                                color: Color::BLACK,
                                font_size: 32.0,
                                ..default()
                            },
                        ),
                    ));
                });

            parent
                .spawn((
                    Quit,
                    ButtonBundle {
                        style: Style {
                            padding: UiRect::all(Val::Px(5.0)),
                            margin: UiRect::all(Val::Px(5.0)),
                            ..default()
                        },
                        background_color: Color::ORANGE.with_a(0.5).into(),
                        ..default()
                    },
                ))
                .with_children(|parent| {
                    parent.spawn((
                        Quit,
                        TextBundle::from_section(
                            "Quit",
                            TextStyle {
                                color: Color::BLACK,
                                font_size: 32.0,
                                ..default()
                            },
                        ),
                    ));
                });
        });
}

pub(crate) fn handle_menu_button<T: Component + States>(
    events: Query<(&Interaction, &T), (With<Button>, Changed<Interaction>)>,
    mut next_gs: ResMut<NextState<T>>,
) {
    events.iter().for_each(|(i, gs)| match i {
        Interaction::Pressed => {
            next_gs.set(gs.clone());
        }
        _ => (),
    });
}

fn handle_menu_quit(
    events: Query<&Interaction, (With<Quit>, With<Button>, Changed<Interaction>)>,
    mut writer: EventWriter<AppExit>,
) {
    events
        .iter()
        .filter(|&interaction| *interaction == Interaction::Pressed)
        .for_each(|_| writer.send(AppExit));
}

/// Used to return to the menu
pub(crate) fn exit_to_menu(
    mut events: EventReader<KeyboardInput>,
    mut next_state: ResMut<NextState<GameState>>,
) {
    events
        .read()
        .filter(
            |KeyboardInput {
                 key_code, state, ..
             }| {
                *key_code == Some(KeyCode::Escape) && *state == ButtonState::Pressed
            },
        )
        .for_each(|_| {
            next_state.set(GameState::Menu);
        })
}
