#include <iostream>
#include <ostream>
#include <DangerousRacers/Scenes/Levels/level_one.h>

#include "SFML/Window/Event.hpp"

LevelOneScene::LevelOneScene (SceneManager& _sceneManager) : Scene (_sceneManager, "DebugLevelScene") {
    backgroundTexture.loadFromFile("assets/racing_bg.png");
    backgroundSprite.setTexture(backgroundTexture);
    backgroundSprite.setPosition(0, -720);
}

void LevelOneScene::leave() {
    sceneManager.getGameWindow().setMouseCursorVisible(true);
}

void LevelOneScene::reset() {
    obstacleManager.reset();
    bgYOffset = -720.f;
    speed = 200.f;

    player.moveTo(405.f/2, 720.f/2, 0.f);
}

void LevelOneScene::start() {
    Scene::start();
    reset();
    sceneManager.getGameWindow().setMouseCursorVisible(false);
}

void LevelOneScene::update (const float deltaTime) {
    const float delta = deltaTime + (distanceTraveled / 5000000.f);
    std::cout << delta << " | " << deltaTime << std::endl;

    Scene::update(delta);
    // Update player movement before anything else
    player.update(delta);

    // Check for collisions

    if (const auto collision = obstacleManager.obstacleCollides(player.getSprite().getGlobalBounds()); !player.isInvincible() && collision == ObstacleManager::DAMAGE) {
        std::cout << "Collision!\n";
        health -= 0.1f;
        if (health <= 0) speed = 50.f;
        player.setInvincibility(1.5f);
    } else if (collision == ObstacleManager::PICKUP_FUEL) fuel += 0.1f;
    else if (collision == ObstacleManager::PICKUP_HEALTH) health += 0.1f;

    health = std::clamp(health, 0.f, 1.f);
    fuel = std::clamp(fuel, 0.f, 1.f);

    if (!player.isInvincible() && health <= 0) {
        sceneManager.changeScene("TutorialOverScene");
        return;
    }

    // Scroll BG
    bgYOffset += delta * speed;
    if (bgYOffset >= 0) bgYOffset = -720.f;
    else if (bgYOffset < -720.f) bgYOffset = 0.f;
    backgroundSprite.setPosition(0, bgYOffset);

    // Move obstacles (and maybe spawn?)
    obstacleManager.update(delta);

    distanceTraveled += delta * speed;
    scoreLabel.setText("Distance: " + std::to_string(static_cast<int>(distanceTraveled)));

    fuel -= deltaTime * 0.025f;
    if (fuel <= 0) {
        sceneManager.changeScene("TutorialOverScene");
        return;
    }

    fuelMeter.setValue(fuel);
    damageMeter.setValue(health);
}

void LevelOneScene::render (sf::RenderWindow& window) {
    Scene::render (window);
    window.draw(backgroundSprite);

    obstacleManager.render(window);

    // Draw player here, to be on top of obstacles
    player.render(window);

    // Draw UI components last
    scoreLabel.render(window);

    fuelMeter.render(window);
    damageMeter.render(window);
}

void LevelOneScene::eventHandler (sf::Event& event) {
    Scene::eventHandler (event);

    if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
        this->sceneManager.changeScene("MainMenu");
        return;
    }

    if (event.type == sf::Event::MouseMoved)
        player.moveTo(std::clamp(event.mouseMove.x, 32, 373), player.getPosition().y, 0.025f);
}