#include "enemy_manager.hpp"

#include <algorithm>  // Para std::ranges::any_of

#include "game/entities/enemy.hpp"  // Para Enemy
#include "utils/utils.hpp"          // Para checkCollision

// Añade un enemigo a la colección
void EnemyManager::addEnemy(std::shared_ptr<Enemy> enemy) {
    enemies_.push_back(std::move(enemy));
}

// Elimina todos los enemigos
void EnemyManager::clear() {
    enemies_.clear();
}

// Elimina el último enemigo de la colección
void EnemyManager::removeLastEnemy() {
    if (!enemies_.empty()) {
        enemies_.pop_back();
    }
}

// Comprueba si no hay enemigos
auto EnemyManager::isEmpty() const -> bool {
    return enemies_.empty();
}

// Actualiza todos los enemigos
void EnemyManager::update(float delta_time) {
    for (const auto& enemy : enemies_) {
        enemy->update(delta_time);
    }
}

// Renderiza todos los enemigos
void EnemyManager::render() {
    for (const auto& enemy : enemies_) {
        enemy->render();
    }
}

#ifdef _DEBUG
// Solo actualiza animaciones sin mover enemigos
void EnemyManager::updateAnimations(float delta_time) {
    for (const auto& enemy : enemies_) {
        enemy->updateAnimation(delta_time);
    }
}

// Resetea todos los enemigos a su posición inicial
void EnemyManager::resetPositions(const std::vector<Enemy::Data>& enemy_data) {
    const int COUNT = std::min(static_cast<int>(enemies_.size()), static_cast<int>(enemy_data.size()));
    for (int i = 0; i < COUNT; ++i) {
        enemies_[i]->resetToInitialPosition(enemy_data[i]);
    }
}

// Número de enemigos
auto EnemyManager::getCount() const -> int {
    return static_cast<int>(enemies_.size());
}

// Acceso a un enemigo por índice
auto EnemyManager::getEnemy(int index) -> std::shared_ptr<Enemy>& {
    return enemies_.at(index);
}
#endif

// Comprueba si hay colisión con algún enemigo
auto EnemyManager::checkCollision(SDL_FRect& rect) -> bool {
    return std::ranges::any_of(enemies_, [&rect](const auto& enemy) {
        return ::checkCollision(rect, enemy->getCollider());
    });
}
