use rand::prelude::*;
use rusty_engine::prelude::*;

#[derive(Resource)]
struct GameState {
    high_score: u32,
    score: u32,
    enemy_index: i32,
    spawn_timer: Timer,
}

impl Default for GameState {
    fn default() -> Self {
        Self {
            high_score: 0,
            score: 0,
            enemy_index: 0,
            spawn_timer: Timer::from_seconds(2.0, TimerMode::Repeating),
        }
    }
}

fn main() {
    let mut game = Game::new();

    game.window_settings(Window {
        title: "Rusty Engine Tutorial".to_string(),
        ..Default::default()
    });

    game.audio_manager
        .play_music(MusicPreset::WhimsicalPopsicle, 0.2);

    let player = game.add_sprite("player", SpritePreset::RacingCarBlue);
    player.collision = true;
    // player.translation = Vec2::new(200.0, 100.0);
    // player.rotation = UP;
    // player.scale = 3.0;
    // player.layer = 0.0;

    let score = game.add_text("score", "Score: 0");
    score.translation = Vec2::new(520.0, 320.0);

    let high_score = game.add_text("high_score", "High Score: 0");
    high_score.translation = Vec2::new(-520.0, 320.0);

    game.add_logic(game_logic);
    game.run(GameState::default());
}

fn game_logic(engine: &mut Engine, game_state: &mut GameState) {
    if engine.keyboard_state.just_pressed(KeyCode::KeyQ) {
        engine.should_exit = true;
    }

    let offset = ((engine.time_since_startup_f64 * 3.0).cos() * 5.0) as f32;

    let score = engine.texts.get_mut("score").unwrap();
    score.translation.x = engine.window_dimensions.x / 2.0 - 80.0;
    score.translation.y = engine.window_dimensions.y / 2.0 - 30.0 + offset;
    let high_score = engine.texts.get_mut("high_score").unwrap();
    high_score.translation.x = -engine.window_dimensions.x / 2.0 + 110.0;
    high_score.translation.y = engine.window_dimensions.y / 2.0 - 30.0;

    // game_state.current_score += 1;
    // println!("Current Score: {}", game_state.current_score);
    engine.show_colliders = true;

    for event in engine.collision_events.drain(..) {
        println!(
            "Collision detected between {} and {}",
            event.pair.0, event.pair.1
        );

        if event.state == CollisionState::Begin && event.pair.one_starts_with("player") {
            for label in [event.pair.0, event.pair.1] {
                if label != "player" {
                    engine.sprites.remove(&label);
                }
            }

            game_state.score += 1;
            let score = engine.texts.get_mut("score").unwrap();
            score.value = format!("Current Score: {}", game_state.score);

            if game_state.score > game_state.high_score {
                game_state.high_score = game_state.score;
                let high_score = engine.texts.get_mut("high_score").unwrap();
                high_score.value = format!("High Score: {}", game_state.high_score);
            }

            engine.audio_manager.play_sfx(SfxPreset::Minimize1, 0.5);
        }
    }

    const MOVEMENT_SPEED: f32 = 100.0;
    let player = engine.sprites.get_mut("player").unwrap();
    if engine
        .keyboard_state
        .pressed_any(&[KeyCode::KeyW, KeyCode::ArrowUp])
    {
        player.translation.y += MOVEMENT_SPEED * engine.delta_f32;
    }
    if engine
        .keyboard_state
        .pressed_any(&[KeyCode::KeyS, KeyCode::ArrowDown])
    {
        player.translation.y -= MOVEMENT_SPEED * engine.delta_f32;
    }
    if engine
        .keyboard_state
        .pressed_any(&[KeyCode::KeyD, KeyCode::ArrowRight])
    {
        player.translation.x += MOVEMENT_SPEED * engine.delta_f32;
    }
    if engine
        .keyboard_state
        .pressed_any(&[KeyCode::KeyA, KeyCode::ArrowLeft])
    {
        player.translation.x -= MOVEMENT_SPEED * engine.delta_f32;
    }

    if game_state.spawn_timer.tick(engine.delta).just_finished() {
        let enemy_label = format!("enemy_{}", game_state.enemy_index);
        game_state.enemy_index += 1;

        let enemy = engine.add_sprite(&enemy_label, SpritePreset::RacingCarGreen);
        enemy.translation.x = thread_rng().gen_range(-550.0..550.0);
        enemy.translation.y = thread_rng().gen_range(-300.0..300.0);
        enemy.collision = true;
    }

    // if engine.mouse_state.just_pressed(MouseButton::Left) {
    //     if let Some(mouse_location) = engine.mouse_state.location() {
    //     }
    // }

    if engine.keyboard_state.just_pressed(KeyCode::KeyR) {
        game_state.score = 0;
        let score = engine.texts.get_mut("score").unwrap();
        score.value = format!("Current Score: {}", game_state.score);
    }
}
