use crate::GameState;
use bevy::{color::palettes::css::BLACK, prelude::*};
use shared::{HEDZ_GREEN, HEDZ_PURPLE, control::CharacterInputEnabled, loading_assets::UIAssets};

#[derive(States, Default, Clone, Eq, PartialEq, Debug, Hash)]
#[states(scoped_entities)]
enum PauseMenuState {
    #[default]
    Closed,
    Open,
}

#[derive(Component, PartialEq, Eq, Clone, Copy)]
enum ProgressBar {
    Music,
    Sound,
}

#[derive(Resource)]
struct PauseMenuSelection(ProgressBar);

pub fn plugin(app: &mut App) {
    app.init_state::<PauseMenuState>();

    app.add_systems(Update, open_pause_menu.run_if(in_state(GameState::Playing)));
    app.add_systems(
        Update,
        (selection_input, selection_changed).run_if(in_state(PauseMenuState::Open)),
    );
    app.add_systems(OnEnter(PauseMenuState::Open), setup);
}

fn open_pause_menu(
    state: Res<State<PauseMenuState>>,
    mut next_state: ResMut<NextState<PauseMenuState>>,
    mut char_controls: ResMut<CharacterInputEnabled>,
    keyboard: Res<ButtonInput<KeyCode>>,
) {
    if keyboard.just_pressed(KeyCode::Escape) {
        let menu_open = match state.get() {
            PauseMenuState::Closed => {
                next_state.set(PauseMenuState::Open);
                true
            }
            PauseMenuState::Open => {
                next_state.set(PauseMenuState::Closed);
                false
            }
        };

        if menu_open {
            *char_controls = CharacterInputEnabled::Off;
        } else {
            *char_controls = CharacterInputEnabled::On;
        }
    }
}

fn setup(mut commands: Commands, assets: Res<UIAssets>) {
    commands.spawn((
        Name::new("pause-menu"),
        Node {
            width: Val::Percent(100.0),
            height: Val::Percent(100.0),
            flex_direction: FlexDirection::Column,
            align_items: AlignItems::Center,
            justify_content: JustifyContent::Center,
            row_gap: Val::Px(10.),
            ..default()
        },
        BackgroundColor(Color::linear_rgba(0., 0., 0., 0.6)),
        StateScoped(PauseMenuState::Open),
        children![
            spawn_progress(ProgressBar::Music, 100, assets.font.clone()),
            spawn_progress(ProgressBar::Sound, 80, assets.font.clone())
        ],
    ));

    commands.insert_resource(PauseMenuSelection(ProgressBar::Music));
}

fn spawn_progress(bar: ProgressBar, value: u8, font: Handle<Font>) -> impl Bundle {
    (
        Node {
            width: Val::Px(500.0),
            height: Val::Px(60.0),
            border: UiRect::all(Val::Px(8.)),
            align_items: AlignItems::Center,
            row_gap: Val::Px(10.),
            ..default()
        },
        BackgroundColor(BLACK.into()),
        BorderRadius::all(Val::Px(100.)),
        BorderColor(HEDZ_PURPLE.into()),
        BoxShadow::new(
            BLACK.into(),
            Val::Px(2.),
            Val::Px(2.),
            Val::Px(4.),
            Val::Px(4.),
        ),
        bar,
        children![
            (
                Node {
                    width: Val::Percent(100.0),
                    margin: UiRect::left(Val::Px(10.)),
                    ..default()
                },
                Text::new(match bar {
                    ProgressBar::Music => "MUSIC".to_string(),
                    ProgressBar::Sound => "SOUND".to_string(),
                }),
                TextFont {
                    font: font.clone(),
                    font_size: 16.0,
                    ..Default::default()
                },
                TextColor(HEDZ_GREEN.into()),
                TextLayout::new_with_justify(JustifyText::Left),
            ),
            (
                Node {
                    margin: UiRect::horizontal(Val::Px(5.)),
                    ..default()
                },
                Text::new("<".to_string()),
                TextFont {
                    font: font.clone(),
                    font_size: 16.0,
                    ..Default::default()
                },
                TextColor(HEDZ_GREEN.into()),
                TextLayout::new_with_justify(JustifyText::Left).with_no_wrap(),
            ),
            (
                Text::new(format!("{value}",)),
                TextFont {
                    font: font.clone(),
                    font_size: 16.0,
                    ..Default::default()
                },
                TextColor(HEDZ_GREEN.into()),
                TextLayout::new_with_justify(JustifyText::Left).with_no_wrap(),
            ),
            (
                Node {
                    margin: UiRect::horizontal(Val::Px(5.)),
                    ..default()
                },
                Text::new(">".to_string()),
                TextFont {
                    font,
                    font_size: 16.0,
                    ..Default::default()
                },
                TextColor(HEDZ_GREEN.into()),
                TextLayout::new_with_justify(JustifyText::Left).with_no_wrap(),
            )
        ],
    )
}

fn selection_input(mut state: ResMut<PauseMenuSelection>, keyboard: Res<ButtonInput<KeyCode>>) {
    if keyboard.just_pressed(KeyCode::ArrowUp) || keyboard.just_pressed(KeyCode::ArrowDown) {
        state.0 = match state.0 {
            ProgressBar::Music => ProgressBar::Sound,
            ProgressBar::Sound => ProgressBar::Music,
        }
    }
}

fn selection_changed(
    state: Res<PauseMenuSelection>,
    mut query: Query<(&mut BorderColor, &ProgressBar)>,
) {
    if state.is_changed() {
        for (mut border, bar) in query.iter_mut() {
            border.0 = if *bar == state.0 {
                HEDZ_GREEN.into()
            } else {
                HEDZ_PURPLE.into()
            }
        }
    }
}
