#include "ui_message.h"
#include <cmath>    // Para pow
#include "screen.h" // Para param y TEXT_CENTER

// Constructor: inicializa el renderizador, el texto y el color del mensaje
UIMessage::UIMessage(std::shared_ptr<Text> text_renderer, const std::string &message_text, const Color &color)
    : text_renderer_(text_renderer), text_(message_text), color_(color) {}

// Muestra el mensaje en la posición base_x, base_y con animación de entrada desde arriba
void UIMessage::show()
{
    if (visible_ && target_y_ == 0.0f)
        return; // Ya está visible y quieto

    start_y_ = DESP_; // Empieza 8 píxeles arriba de la posición base
    target_y_ = 0.0f; // La posición final es la base
    y_offset_ = start_y_;
    anim_step_ = 0;
    animating_ = true;
    visible_ = true;
}

// Oculta el mensaje con animación de salida hacia arriba
void UIMessage::hide()
{
    if (!visible_)
        return;

    start_y_ = y_offset_; // Comienza desde la posición actual
    target_y_ = DESP_;    // Termina 8 píxeles arriba de la base
    anim_step_ = 0;
    animating_ = true;
}

// Actualiza el estado de la animación (debe llamarse cada frame)
void UIMessage::update()
{
    if (animating_)
    {
        updateAnimation();
    }
}

// Interpola la posición vertical del mensaje usando ease out cubic
void UIMessage::updateAnimation()
{
    anim_step_++;
    float t = static_cast<float>(anim_step_) / ANIMATION_STEPS;

    if (target_y_ > start_y_)
    {
        // Animación de entrada (ease out cubic)
        t = 1 - pow(1 - t, 3);
    }
    else
    {
        // Animación de salida (ease in cubic)
        t = pow(t, 3);
    }

    y_offset_ = start_y_ + (target_y_ - start_y_) * t;

    if (anim_step_ >= ANIMATION_STEPS)
    {
        y_offset_ = target_y_;
        animating_ = false;
        if (target_y_ < 0.0f)
            visible_ = false;
    }
}

// Dibuja el mensaje en pantalla si está visible
void UIMessage::render()
{
    if (visible_)
    {
        text_renderer_->writeDX(
            TEXT_COLOR | TEXT_CENTER,
            base_x_,
            base_y_ + y_offset_,
            text_,
            -2,
            color_);
    }
}

// Devuelve true si el mensaje está visible actualmente
bool UIMessage::isVisible() const
{
    return visible_;
}

// Permite actualizar la posición del mensaje (por ejemplo, si el menú se mueve)
void UIMessage::setPosition(float new_base_x, float new_base_y)
{
    base_x_ = new_base_x;
    base_y_ = new_base_y;
}