#include "dynamic_theme.hpp"
#include <algorithm>  // for std::min

DynamicTheme::DynamicTheme(const char* name_en, const char* name_es,
                           int text_r, int text_g, int text_b,
                           std::vector<DynamicThemeKeyframe> keyframes,
                           bool loop)
    : name_en_(name_en),
      name_es_(name_es),
      text_r_(text_r), text_g_(text_g), text_b_(text_b),
      keyframes_(std::move(keyframes)),
      loop_(loop),
      current_keyframe_index_(0),
      target_keyframe_index_(1),
      transition_progress_(0.0f),
      paused_(false) {
    // Validación: mínimo 2 keyframes
    if (keyframes_.size() < 2) {
        // Fallback: duplicar primer keyframe si solo hay 1
        if (keyframes_.size() == 1) {
            keyframes_.push_back(keyframes_[0]);
        }
    }

    // Asegurar que target_keyframe_index es válido
    if (target_keyframe_index_ >= keyframes_.size()) {
        target_keyframe_index_ = 0;
    }
}

void DynamicTheme::update(float delta_time) {
    if (paused_) return;  // No actualizar si está pausado

    // Obtener duración del keyframe objetivo
    float duration = keyframes_[target_keyframe_index_].duration;
    if (duration <= 0.0f) {
        duration = 1.0f;  // Fallback si duración inválida
    }

    // Avanzar progreso
    transition_progress_ += delta_time / duration;

    // Si completamos la transición, avanzar al siguiente keyframe
    if (transition_progress_ >= 1.0f) {
        advanceToNextKeyframe();
    }
}

void DynamicTheme::resetProgress() {
    current_keyframe_index_ = 0;
    target_keyframe_index_ = 1;
    if (target_keyframe_index_ >= keyframes_.size()) {
        target_keyframe_index_ = 0;
    }
    transition_progress_ = 0.0f;
}

void DynamicTheme::advanceToNextKeyframe() {
    // Mover al siguiente keyframe
    current_keyframe_index_ = target_keyframe_index_;
    target_keyframe_index_++;

    // Loop: volver al inicio si llegamos al final
    if (target_keyframe_index_ >= keyframes_.size()) {
        if (loop_) {
            target_keyframe_index_ = 0;
        } else {
            // Si no hay loop, quedarse en el último keyframe
            target_keyframe_index_ = keyframes_.size() - 1;
        }
    }

    // Reiniciar progreso
    transition_progress_ = 0.0f;
}

Color DynamicTheme::getBallColor(size_t ball_index, float progress) const {
    // Obtener keyframes actual y objetivo
    const auto& current_kf = keyframes_[current_keyframe_index_];
    const auto& target_kf = keyframes_[target_keyframe_index_];

    // Si paletas vacías, retornar blanco
    if (current_kf.ball_colors.empty() || target_kf.ball_colors.empty()) {
        return {255, 255, 255};
    }

    // Obtener colores de ambos keyframes (con wrap)
    size_t current_palette_size = current_kf.ball_colors.size();
    size_t target_palette_size = target_kf.ball_colors.size();

    Color c1 = current_kf.ball_colors[ball_index % current_palette_size];
    Color c2 = target_kf.ball_colors[ball_index % target_palette_size];

    // Interpolar entre ambos colores usando progreso interno
    // (progress parámetro será usado en PHASE 3 para LERP externo)
    float t = transition_progress_;
    return {
        static_cast<int>(lerp(c1.r, c2.r, t)),
        static_cast<int>(lerp(c1.g, c2.g, t)),
        static_cast<int>(lerp(c1.b, c2.b, t))
    };
}

void DynamicTheme::getBackgroundColors(float progress,
                                       float& tr, float& tg, float& tb,
                                       float& br, float& bg, float& bb) const {
    // Obtener keyframes actual y objetivo
    const auto& current_kf = keyframes_[current_keyframe_index_];
    const auto& target_kf = keyframes_[target_keyframe_index_];

    // Interpolar colores de fondo usando progreso interno
    // (progress parámetro será usado en PHASE 3 para LERP externo)
    float t = transition_progress_;

    tr = lerp(current_kf.bg_top_r, target_kf.bg_top_r, t);
    tg = lerp(current_kf.bg_top_g, target_kf.bg_top_g, t);
    tb = lerp(current_kf.bg_top_b, target_kf.bg_top_b, t);

    br = lerp(current_kf.bg_bottom_r, target_kf.bg_bottom_r, t);
    bg = lerp(current_kf.bg_bottom_g, target_kf.bg_bottom_g, t);
    bb = lerp(current_kf.bg_bottom_b, target_kf.bg_bottom_b, t);
}

void DynamicTheme::getNotificationBackgroundColor(int& r, int& g, int& b) const {
    // Obtener keyframes actual y objetivo
    const auto& current_kf = keyframes_[current_keyframe_index_];
    const auto& target_kf = keyframes_[target_keyframe_index_];

    // Interpolar color de fondo de notificación usando progreso interno
    float t = transition_progress_;

    r = static_cast<int>(lerp(static_cast<float>(current_kf.notif_bg_r), static_cast<float>(target_kf.notif_bg_r), t));
    g = static_cast<int>(lerp(static_cast<float>(current_kf.notif_bg_g), static_cast<float>(target_kf.notif_bg_g), t));
    b = static_cast<int>(lerp(static_cast<float>(current_kf.notif_bg_b), static_cast<float>(target_kf.notif_bg_b), t));
}
