use bevy::input::keyboard::{Key, KeyboardInput};
use bevy::prelude::*;

use crate::consts::TITLE_COLOR;
use crate::resources::NumbersFont;
use crate::{gameplay::Gameplay, resources::{AppState, TitleFont}};

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Component)]
pub struct Pause;

impl Pause {

    pub fn load(
        mut commands: Commands,
        mut gameplay_query: Query<&mut Visibility, With<Gameplay>>,
        title_font: Res<TitleFont>,
        normal_font: Res<NumbersFont>,

    ) {
        for mut visibility in &mut gameplay_query {
            *visibility = Visibility::Hidden;
        }
        commands.spawn((
            Self,
            Text::new("Paused"),
            TextShadow::default(),
            TextColor(TITLE_COLOR),
            TextFont {
                font: title_font.clone_weak(),
                font_size: 92.0,
                ..default()
            },
            TextLayout::new_with_justify(JustifyText::Center),
            Node {
                position_type: PositionType::Absolute,
                top: Val::ZERO,
                width: Val::Percent(100.0),
                ..default()
            },
        ));

        let mut y = 140.0;
        for text in [
            "Left click (LMB): set cell",
            "Right click (RMB) or C-LMB: mark a cell as unsettable",
            "Middle click (MMB) or S-LMB: mark the cell as possibly settable",
            "LMB on a set cell: unset it",
            "RMB on an unsettable cell: make it settable",
            "MMB on a cell marked as possibly settable: unmark it",
            "F2: mute/unmute",
            "R key: reset current board",
            "Escape: back (quit current game, unpause, or quit the app)",
            "Pause: pause/unpause the game",
            "C-Q: quit the app",
        ] {
            commands.spawn((
                Self,
                Text::new(text),
                TextColor(TITLE_COLOR),
                TextFont {
                    font: normal_font.clone_weak(),
                    font_size: 32.0,
                    ..default()
                },
                TextLayout::new_with_justify(JustifyText::Left),
                Node {
                    position_type: PositionType::Absolute,
                    top: Val::Px(y),
                    left: Val::Percent(12.0),
                    width: Val::Percent(76.0),
                    ..default()
                },
            ));
            y += 50.0;
        }
    }

    pub fn unload(
        mut commands: Commands,
        mut gameplay_query: Query<&mut Visibility, With<Gameplay>>,
        self_query: Query<Entity, With<Self>>,
    ) {
        for id in &self_query {
            commands.entity(id).despawn();
        }
        for mut visibility in &mut gameplay_query {
            *visibility = Visibility::Visible;
        }
    }

    pub fn key_events(
        mut keyboard: EventReader<KeyboardInput>,
        mut next_state: ResMut<NextState<AppState>>,
    ) {
        for (input, _) in keyboard.par_read() {
            if input.state.is_pressed() && !input.repeat {
                match input.logical_key {
                    Key::Escape |
                    Key::Pause => {
                        next_state.set(AppState::Gameplay);
                        return;
                    }

                    _ => (),
                }
            }
        }
    }
}
