use bevy::{color::palettes::css::{BLACK, CRIMSON, DARK_GREY}, prelude::*};

use crate::GameState;

#[derive(Component)]
struct OnMainMenuScreen;

pub fn plugin(app: &mut App) {
    app
        .add_systems(OnEnter(GameState::Menu), setup_main_menu)
        .add_systems(OnExit(GameState::Menu), (
            remove_camera_2d,
            despawn_screen::<OnMainMenuScreen>
        ))
        .add_systems(Update, button_system.run_if(in_state(GameState::Menu)));
}

#[derive(Component)]
struct MainMenu;

#[derive(Component)]
enum MenuButton {
    Play,
    Settings,
    Quit
}

const TEXT_COLOR: Color = Color::srgb(0.9, 0.9, 0.9);

const NORMAL_BUTTON: Color = Color::srgb(0.15, 0.15, 0.15);
const HOVERED_BUTTON: Color = Color::srgb(0.25, 0.25, 0.25);
const HOVERED_PRESSED_BUTTON: Color = Color::srgb(0.25, 0.65, 0.25);
const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35);

fn setup_main_menu(mut commands: Commands) {
    commands.spawn(Camera2d);

    let button_node = Node {
        width: Val::Px(300.0),
        height: Val::Px(65.0),
        margin: UiRect::all(Val::Px(20.0)),
        justify_content: JustifyContent::Center,
        align_items: AlignItems::Center,
        ..default()
    };

    let button_text_font = TextFont {
        font_size: 33.0,
        ..default()
    };

    commands
        .spawn((
            Node {
                width: Val::Percent(100.0),
                height: Val::Percent(100.0),
                flex_direction: FlexDirection::Column,
                align_items: AlignItems::Center,
                justify_content: JustifyContent::Center,
                ..default()
            },
            OnMainMenuScreen
        ))
        .insert(MainMenu)
        .with_children(|parent| {
            parent.spawn((
                Node {
                    flex_direction: FlexDirection::Column,
                    align_items: AlignItems::Center,
                    ..default()
                },
                BackgroundColor(BLACK.into()),
            ))
            .with_children(|parent| {
                // Display the game name
                parent.spawn((
                    Text::new("Among Me"),
                    TextFont {
                        font_size: 67.0,
                        ..default()
                    },
                    TextColor(TEXT_COLOR),
                    Node {
                        margin: UiRect::all(Val::Px(50.0)),
                        ..default()
                    },
                ));

                // Display three buttons for each action available from the main menu:
                // - new game
                // - settings
                // - quit
                parent
                    .spawn((
                        Button,
                        button_node.clone(),
                        BackgroundColor(NORMAL_BUTTON),
                        MenuButton::Play,
                    ))
                    .with_children(|parent| {
                        parent.spawn((
                            Text::new("New Game"),
                            button_text_font.clone(),
                            TextColor(TEXT_COLOR),
                        ));
                    });
                parent
                    .spawn((
                        Button,
                        button_node.clone(),
                        BackgroundColor(NORMAL_BUTTON),
                        MenuButton::Quit,
                    ))
                    .with_children(|parent| {
                        parent.spawn((
                            Text::new("Quit"),
                            button_text_font.clone(),
                            TextColor(TEXT_COLOR),
                        ));
                    });
            });
        });
}

fn button_system(
    mut interaction_query: Query<
        (&Interaction, &MenuButton),
        (Changed<Interaction>, With<Button>),
    >,
    mut game_state: ResMut<NextState<GameState>>,
) {
    for (interaction, button) in interaction_query.iter() {
        if *interaction == Interaction::Pressed {
            match button {
                MenuButton::Play => game_state.set(GameState::Playing),
                MenuButton::Settings => println!("Settings pressed"),
                MenuButton::Quit => std::process::exit(0),
            }
        }
    }
}

fn remove_camera_2d(mut commands: Commands, camera_query: Query<Entity, With<Camera2d>>) {
    for camera in camera_query.iter() {
        commands.entity(camera).despawn_recursive();
    }
}

fn despawn_screen<T: Component>(to_despawn: Query<Entity, With<T>>, mut commands: Commands) {
    for entity in &to_despawn {
        commands.entity(entity).despawn_recursive();
    }
}
