#include "game/entities/key.hpp"

#include <cmath>  // Para std::sin

#include "core/rendering/sprite/animated_sprite.hpp"  // Para AnimatedSprite
#include "core/resources/resource_cache.hpp"          // Para Resource

// Constructor: carga la animación, posiciona el sprite y crea el collider
Key::Key(const Data& data)
    : sprite_(std::make_shared<AnimatedSprite>(Resource::Cache::get()->getAnimationData(data.animation_path))),
      id_(data.id),
      base_y_(data.y) {
    sprite_->setPosX(data.x);
    sprite_->setPosY(data.y);
    sprite_->setCurrentAnimation("default");
    collider_ = sprite_->getRect();
}

// Pinta la llave en pantalla
void Key::render() {
    sprite_->render();
}

// Avanza la animación de la llave y aplica el movimiento flotante sinusoidal
void Key::update(float delta_time) {
    if (is_paused_) {
        return;
    }
    sprite_->animate(delta_time);

    // Oscilacion sinusoidal sincronizada (mismo tiempo global para todas las llaves)
    const float T = static_cast<float>(SDL_GetTicks()) / 1000.0F;
    const float OFFSET = std::sin(T * 2.0F * SDL_PI_F / FLOAT_PERIOD_S) * FLOAT_AMPLITUDE;
    sprite_->setPosY(base_y_ + OFFSET);
}

// Posición base (el collider y el tracker usan la posición sin oscilación)
auto Key::getPos() const -> SDL_FPoint {
    return SDL_FPoint{.x = sprite_->getX(), .y = base_y_};
}

#ifdef _DEBUG
// Mueve la llave a la posición indicada (sprite + collider). Solo editor.
void Key::setPosition(float x, float y) {
    sprite_->setPosX(x);
    sprite_->setPosY(y);
    base_y_ = y;
    collider_ = sprite_->getRect();
}
#endif
