// continue_system.cpp - Implementación de la pantalla de continue

#include "game/systems/continue_system.hpp"

#include <cstdint>

#include "core/audio/audio.hpp"
#include "core/defaults.hpp"
#include "core/input/input.hpp"
#include "core/input/input_types.hpp"
#include "game/scenes/game_scene.hpp"  // GameOverState (definición completa)

namespace Systems::ContinueScreen {
namespace {

// Si el countdown ha bajado de 0, transiciona a GAME_OVER con su timer.
void checkAndApplyTimeout(Context& ctx) {
    if (ctx.counter < 0) {
        ctx.state = GameOverState::GAME_OVER;
        ctx.game_over_timer = Defaults::Game::GAME_OVER_DURATION;
    }
}

void revivePlayer(Context& ctx, uint8_t player_id) {
    ctx.score_per_player[player_id] = 0;
    ctx.lives_per_player[player_id] = Defaults::Game::STARTING_LIVES;
    ctx.hit_timer_per_player[player_id] = 0.0F;

    if (player_id == 0) {
        ctx.match_config.jugador1_actiu = true;
    } else {
        ctx.match_config.jugador2_actiu = true;
    }

    const Vec2 SPAWN = ctx.get_spawn_point(player_id);
    ctx.ships[player_id].init(&SPAWN, /*activar_invulnerabilitat=*/true);
}

}  // namespace

void update(Context& ctx, float delta_time) {
    ctx.tick_timer -= delta_time;
    if (ctx.tick_timer > 0.0F) {
        return;
    }
    ctx.counter--;
    ctx.tick_timer = Defaults::Game::CONTINUE_TICK_DURATION;

    checkAndApplyTimeout(ctx);

    // Solo pita el tick si seguimos en CONTINUE (no transitamos a GAME_OVER)
    if (ctx.state == GameOverState::CONTINUE) {
        Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
    }
}

void processInput(Context& ctx) {
    auto* input = Input::get();

    const bool P1_START = input->checkActionPlayer1(InputAction::START, Input::DO_NOT_ALLOW_REPEAT);
    const bool P2_START = input->checkActionPlayer2(InputAction::START, Input::DO_NOT_ALLOW_REPEAT);

    if (P1_START || P2_START) {
        // ¿Quedan continues?
        if (!Defaults::Game::INFINITE_CONTINUES &&
            ctx.continues_used >= Defaults::Game::MAX_CONTINUES) {
            ctx.state = GameOverState::GAME_OVER;
            ctx.game_over_timer = Defaults::Game::GAME_OVER_DURATION;
            return;
        }
        if (!Defaults::Game::INFINITE_CONTINUES) {
            ctx.continues_used++;
        }

        const uint8_t PRIMARY = P1_START ? 0 : 1;
        revivePlayer(ctx, PRIMARY);
        // Si ambos pulsan START, revivimos a los dos.
        if (P1_START && P2_START) {
            revivePlayer(ctx, 1);
        }

        // Reanudar partida.
        ctx.state = GameOverState::NONE;
        ctx.counter = 0;
        ctx.tick_timer = 0.0F;

        Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME);
        return;
    }

    // THRUST/SHOOT acelera el countdown manualmente.
    const bool ACCEL = input->checkActionPlayer1(InputAction::THRUST, Input::DO_NOT_ALLOW_REPEAT) ||
                       input->checkActionPlayer2(InputAction::THRUST, Input::DO_NOT_ALLOW_REPEAT) ||
                       input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT) ||
                       input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT);

    if (ACCEL) {
        ctx.counter--;
        checkAndApplyTimeout(ctx);

        if (ctx.state == GameOverState::CONTINUE) {
            Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
        }

        ctx.tick_timer = Defaults::Game::CONTINUE_TICK_DURATION;
    }
}

}  // namespace Systems::ContinueScreen
