#include "app_logo.hpp"

#include <SDL3/SDL_render.h>  // for SDL_DestroyTexture, SDL_RenderGeometry, SDL_SetTextureAlphaMod

#include <array>     // for std::array
#include <cmath>     // for powf, sinf, cosf
#include <cstdlib>   // for free()
#include <iostream>  // for std::cout
#include <numbers>

#include "defines.hpp"      // for APPLOGO_HEIGHT_PERCENT, getResourcesDirectory
#include "logo_scaler.hpp"  // for LogoScaler

// ============================================================================
// Destructor - Liberar las 4 texturas SDL
// ============================================================================

AppLogo::~AppLogo() {
    if (logo1_base_texture_ != nullptr) {
        SDL_DestroyTexture(logo1_base_texture_);
        logo1_base_texture_ = nullptr;
    }
    if (logo1_native_texture_ != nullptr) {
        SDL_DestroyTexture(logo1_native_texture_);
        logo1_native_texture_ = nullptr;
    }
    if (logo2_base_texture_ != nullptr) {
        SDL_DestroyTexture(logo2_base_texture_);
        logo2_base_texture_ = nullptr;
    }
    if (logo2_native_texture_ != nullptr) {
        SDL_DestroyTexture(logo2_native_texture_);
        logo2_native_texture_ = nullptr;
    }
}

// ============================================================================
// Inicialización - Pre-escalar logos a 2 resoluciones (base y nativa)
// ============================================================================

auto AppLogo::initialize(SDL_Renderer* renderer, int screen_width, int screen_height) -> bool {
    if (logo1_base_texture_ != nullptr) {
        SDL_DestroyTexture(logo1_base_texture_);
        logo1_base_texture_ = nullptr;
    }
    if (logo1_native_texture_ != nullptr) {
        SDL_DestroyTexture(logo1_native_texture_);
        logo1_native_texture_ = nullptr;
    }
    if (logo2_base_texture_ != nullptr) {
        SDL_DestroyTexture(logo2_base_texture_);
        logo2_base_texture_ = nullptr;
    }
    if (logo2_native_texture_ != nullptr) {
        SDL_DestroyTexture(logo2_native_texture_);
        logo2_native_texture_ = nullptr;
    }

    renderer_ = renderer;
    base_screen_width_ = screen_width;
    base_screen_height_ = screen_height;
    screen_width_ = screen_width;
    screen_height_ = screen_height;

    std::string resources_dir = getResourcesDirectory();

    // ========================================================================
    // 1. Detectar resolución nativa del monitor
    // ========================================================================
    if (!LogoScaler::detectNativeResolution(native_screen_width_, native_screen_height_)) {
        std::cout << "No se pudo detectar resolución nativa, usando solo base" << '\n';
        // Fallback: usar resolución base como nativa
        native_screen_width_ = screen_width;
        native_screen_height_ = screen_height;
    }

    // ========================================================================
    // 2. Calcular alturas finales para ambas resoluciones
    // ========================================================================
    int logo_base_target_height = static_cast<int>(base_screen_height_ * APPLOGO_HEIGHT_PERCENT);
    int logo_native_target_height = static_cast<int>(native_screen_height_ * APPLOGO_HEIGHT_PERCENT);

    // ========================================================================
    // 3. Cargar y escalar LOGO1 (data/logo/logo.png) a 2 versiones
    // ========================================================================
    std::string logo1_path = resources_dir + "/data/logo/logo.png";

    // 3a. Versión BASE de logo1
    unsigned char* logo1_base_data = LogoScaler::loadAndScale(
        logo1_path,
        0,  // width calculado automáticamente por aspect ratio
        logo_base_target_height,
        logo1_base_width_,
        logo1_base_height_);
    if (logo1_base_data == nullptr) {
        std::cout << "Error: No se pudo escalar logo1 (base)" << '\n';
        return false;
    }

    logo1_base_texture_ = LogoScaler::createTextureFromBuffer(
        renderer,
        logo1_base_data,
        logo1_base_width_,
        logo1_base_height_);
    free(logo1_base_data);  // Liberar buffer temporal

    if (logo1_base_texture_ == nullptr) {
        std::cout << "Error: No se pudo crear textura logo1 (base)" << '\n';
        return false;
    }

    // Habilitar alpha blending
    SDL_SetTextureBlendMode(logo1_base_texture_, SDL_BLENDMODE_BLEND);

    // 3b. Versión NATIVA de logo1
    unsigned char* logo1_native_data = LogoScaler::loadAndScale(
        logo1_path,
        0,  // width calculado automáticamente
        logo_native_target_height,
        logo1_native_width_,
        logo1_native_height_);
    if (logo1_native_data == nullptr) {
        std::cout << "Error: No se pudo escalar logo1 (nativa)" << '\n';
        return false;
    }

    logo1_native_texture_ = LogoScaler::createTextureFromBuffer(
        renderer,
        logo1_native_data,
        logo1_native_width_,
        logo1_native_height_);
    free(logo1_native_data);

    if (logo1_native_texture_ == nullptr) {
        std::cout << "Error: No se pudo crear textura logo1 (nativa)" << '\n';
        return false;
    }

    SDL_SetTextureBlendMode(logo1_native_texture_, SDL_BLENDMODE_BLEND);

    // ========================================================================
    // 4. Cargar y escalar LOGO2 (data/logo/logo2.png) a 2 versiones
    // ========================================================================
    std::string logo2_path = resources_dir + "/data/logo/logo2.png";

    // 4a. Versión BASE de logo2
    unsigned char* logo2_base_data = LogoScaler::loadAndScale(
        logo2_path,
        0,
        logo_base_target_height,
        logo2_base_width_,
        logo2_base_height_);
    if (logo2_base_data == nullptr) {
        std::cout << "Error: No se pudo escalar logo2 (base)" << '\n';
        return false;
    }

    logo2_base_texture_ = LogoScaler::createTextureFromBuffer(
        renderer,
        logo2_base_data,
        logo2_base_width_,
        logo2_base_height_);
    free(logo2_base_data);

    if (logo2_base_texture_ == nullptr) {
        std::cout << "Error: No se pudo crear textura logo2 (base)" << '\n';
        return false;
    }

    SDL_SetTextureBlendMode(logo2_base_texture_, SDL_BLENDMODE_BLEND);

    // 4b. Versión NATIVA de logo2
    unsigned char* logo2_native_data = LogoScaler::loadAndScale(
        logo2_path,
        0,
        logo_native_target_height,
        logo2_native_width_,
        logo2_native_height_);
    if (logo2_native_data == nullptr) {
        std::cout << "Error: No se pudo escalar logo2 (nativa)" << '\n';
        return false;
    }

    logo2_native_texture_ = LogoScaler::createTextureFromBuffer(
        renderer,
        logo2_native_data,
        logo2_native_width_,
        logo2_native_height_);
    free(logo2_native_data);

    if (logo2_native_texture_ == nullptr) {
        std::cout << "Error: No se pudo crear textura logo2 (nativa)" << '\n';
        return false;
    }

    SDL_SetTextureBlendMode(logo2_native_texture_, SDL_BLENDMODE_BLEND);

    // ========================================================================
    // 5. Inicialmente usar texturas BASE (la resolución de inicio)
    // ========================================================================
    logo1_current_texture_ = logo1_base_texture_;
    logo1_current_width_ = logo1_base_width_;
    logo1_current_height_ = logo1_base_height_;

    logo2_current_texture_ = logo2_base_texture_;
    logo2_current_width_ = logo2_base_width_;
    logo2_current_height_ = logo2_base_height_;

    std::cout << "[Logo] logo.png + logo2.png (base " << logo_base_target_height << "px, nativa " << logo_native_target_height << "px)\n";
    return true;
}

void AppLogo::update(float delta_time, AppMode current_mode) {  // NOLINT(readability-function-cognitive-complexity)
    // Si estamos en SANDBOX, resetear y no hacer nada (logo desactivado)
    if (current_mode == AppMode::SANDBOX) {
        state_ = AppLogoState::HIDDEN;
        timer_ = 0.0f;
        logo1_alpha_ = 0;
        logo2_alpha_ = 0;
        return;
    }

    // Máquina de estados con fade in/out
    timer_ += delta_time;

    switch (state_) {
        case AppLogoState::HIDDEN:
            // Esperando el intervalo de espera
            if (timer_ >= APPLOGO_DISPLAY_INTERVAL) {
                state_ = AppLogoState::FADE_IN;
                timer_ = 0.0f;
                logo1_alpha_ = 0;
                logo2_alpha_ = 0;
                // Elegir UNA animación aleatoria (misma para ambos logos, misma entrada y salida)
                current_animation_ = getRandomAnimation();
            }
            break;

        case AppLogoState::FADE_IN:
            // Fade in: alpha de 0 a 255, con Logo 2 retrasado 0.25s
            {
                // Calcular progreso de cada logo (Logo 2 con retraso)
                float fade_progress_logo1 = timer_ / APPLOGO_ANIMATION_DURATION;
                float fade_progress_logo2 = std::max(0.0f, (timer_ - APPLOGO_LOGO2_DELAY) / APPLOGO_ANIMATION_DURATION);

                // Verificar si fade in completado (cuando logo2 también termina)
                if (fade_progress_logo2 >= 1.0f) {
                    // Fade in completado para ambos logos
                    state_ = AppLogoState::VISIBLE;
                    timer_ = 0.0f;
                    logo1_alpha_ = 255;
                    logo2_alpha_ = 255;
                    // Resetear variables de ambos logos
                    logo1_scale_ = 1.0f;
                    logo1_squash_y_ = 1.0f;
                    logo1_stretch_x_ = 1.0f;
                    logo1_rotation_ = 0.0f;
                    logo2_scale_ = 1.0f;
                    logo2_squash_y_ = 1.0f;
                    logo2_stretch_x_ = 1.0f;
                    logo2_rotation_ = 0.0f;
                } else {
                    // Interpolar alpha con retraso de forma LINEAL (sin easing)
                    logo1_alpha_ = static_cast<int>(std::min(1.0f, fade_progress_logo1) * 255.0f);
                    logo2_alpha_ = static_cast<int>(std::min(1.0f, fade_progress_logo2) * 255.0f);

                    // ================================================================
                    // Aplicar MISMA animación (current_animation_) a ambos logos
                    // con sus respectivos progresos
                    // ================================================================
                    switch (current_animation_) {
                        case AppLogoAnimationType::ZOOM_ONLY:
                            logo1_scale_ = 1.2f - (std::min(1.0f, fade_progress_logo1) * 0.2f);
                            logo1_squash_y_ = 1.0f;
                            logo1_stretch_x_ = 1.0f;
                            logo1_rotation_ = 0.0f;

                            logo2_scale_ = 1.2f - (std::min(1.0f, fade_progress_logo2) * 0.2f);
                            logo2_squash_y_ = 1.0f;
                            logo2_stretch_x_ = 1.0f;
                            logo2_rotation_ = 0.0f;
                            break;

                        case AppLogoAnimationType::ELASTIC_STICK: {
                            float prog1 = std::min(1.0f, fade_progress_logo1);
                            float elastic_t1 = easeOutElastic(prog1);
                            logo1_scale_ = 1.2f - (elastic_t1 * 0.2f);
                            float squash_t1 = easeOutBack(prog1);
                            logo1_squash_y_ = 0.6f + (squash_t1 * 0.4f);
                            logo1_stretch_x_ = 1.0f + (1.0f - logo1_squash_y_) * 0.5f;
                            logo1_rotation_ = 0.0f;

                            float prog2 = std::min(1.0f, fade_progress_logo2);
                            float elastic_t2 = easeOutElastic(prog2);
                            logo2_scale_ = 1.2f - (elastic_t2 * 0.2f);
                            float squash_t2 = easeOutBack(prog2);
                            logo2_squash_y_ = 0.6f + (squash_t2 * 0.4f);
                            logo2_stretch_x_ = 1.0f + (1.0f - logo2_squash_y_) * 0.5f;
                            logo2_rotation_ = 0.0f;
                        } break;

                        case AppLogoAnimationType::ROTATE_SPIRAL: {
                            float prog1 = std::min(1.0f, fade_progress_logo1);
                            float ease_t1 = easeInOutQuad(prog1);
                            logo1_scale_ = 0.3f + (ease_t1 * 0.7f);
                            logo1_rotation_ = (1.0f - prog1) * 6.28f;
                            logo1_squash_y_ = 1.0f;
                            logo1_stretch_x_ = 1.0f;

                            float prog2 = std::min(1.0f, fade_progress_logo2);
                            float ease_t2 = easeInOutQuad(prog2);
                            logo2_scale_ = 0.3f + (ease_t2 * 0.7f);
                            logo2_rotation_ = (1.0f - prog2) * 6.28f;
                            logo2_squash_y_ = 1.0f;
                            logo2_stretch_x_ = 1.0f;
                        } break;

                        case AppLogoAnimationType::BOUNCE_SQUASH: {
                            float prog1 = std::min(1.0f, fade_progress_logo1);
                            float bounce_t1 = easeOutBounce(prog1);
                            logo1_scale_ = 1.0f;
                            float squash_amount1 = (1.0f - bounce_t1) * 0.3f;
                            logo1_squash_y_ = 1.0f - squash_amount1;
                            logo1_stretch_x_ = 1.0f + squash_amount1 * 0.5f;
                            logo1_rotation_ = 0.0f;

                            float prog2 = std::min(1.0f, fade_progress_logo2);
                            float bounce_t2 = easeOutBounce(prog2);
                            logo2_scale_ = 1.0f;
                            float squash_amount2 = (1.0f - bounce_t2) * 0.3f;
                            logo2_squash_y_ = 1.0f - squash_amount2;
                            logo2_stretch_x_ = 1.0f + squash_amount2 * 0.5f;
                            logo2_rotation_ = 0.0f;
                        } break;
                    }
                }
            }
            break;

        case AppLogoState::VISIBLE:
            // Logo completamente visible, esperando duración
            if (timer_ >= APPLOGO_DISPLAY_DURATION) {
                state_ = AppLogoState::FADE_OUT;
                timer_ = 0.0f;
                logo1_alpha_ = 255;
                logo2_alpha_ = 255;
                // NO elegir nueva animación - reutilizar current_animation_ (simetría entrada/salida)
            }
            break;

        case AppLogoState::FADE_OUT:
            // Fade out: alpha de 255 a 0, con Logo 2 retrasado 0.25s (misma animación que entrada)
            {
                // Calcular progreso de cada logo (Logo 2 con retraso)
                float fade_progress_logo1 = timer_ / APPLOGO_ANIMATION_DURATION;
                float fade_progress_logo2 = std::max(0.0f, (timer_ - APPLOGO_LOGO2_DELAY) / APPLOGO_ANIMATION_DURATION);

                // Verificar si fade out completado (cuando logo2 también termina)
                if (fade_progress_logo2 >= 1.0f) {
                    // Fade out completado, volver a HIDDEN
                    state_ = AppLogoState::HIDDEN;
                    timer_ = 0.0f;
                    logo1_alpha_ = 0;
                    logo2_alpha_ = 0;
                    // Resetear variables de ambos logos
                    logo1_scale_ = 1.0f;
                    logo1_squash_y_ = 1.0f;
                    logo1_stretch_x_ = 1.0f;
                    logo1_rotation_ = 0.0f;
                    logo2_scale_ = 1.0f;
                    logo2_squash_y_ = 1.0f;
                    logo2_stretch_x_ = 1.0f;
                    logo2_rotation_ = 0.0f;
                } else {
                    // Interpolar alpha con retraso de forma LINEAL (255 → 0, sin easing)
                    logo1_alpha_ = static_cast<int>((1.0f - std::min(1.0f, fade_progress_logo1)) * 255.0f);
                    logo2_alpha_ = static_cast<int>((1.0f - std::min(1.0f, fade_progress_logo2)) * 255.0f);

                    // ================================================================
                    // Aplicar MISMA animación (current_animation_) de forma invertida
                    // ================================================================
                    switch (current_animation_) {
                        case AppLogoAnimationType::ZOOM_ONLY:
                            logo1_scale_ = 1.0f + (std::min(1.0f, fade_progress_logo1) * 0.2f);
                            logo1_squash_y_ = 1.0f;
                            logo1_stretch_x_ = 1.0f;
                            logo1_rotation_ = 0.0f;

                            logo2_scale_ = 1.0f + (std::min(1.0f, fade_progress_logo2) * 0.2f);
                            logo2_squash_y_ = 1.0f;
                            logo2_stretch_x_ = 1.0f;
                            logo2_rotation_ = 0.0f;
                            break;

                        case AppLogoAnimationType::ELASTIC_STICK: {
                            float prog1 = std::min(1.0f, fade_progress_logo1);
                            logo1_scale_ = 1.0f + (prog1 * prog1 * 0.2f);
                            logo1_squash_y_ = 1.0f + (prog1 * 0.3f);
                            logo1_stretch_x_ = 1.0f - (prog1 * 0.2f);
                            logo1_rotation_ = prog1 * 0.1f;

                            float prog2 = std::min(1.0f, fade_progress_logo2);
                            logo2_scale_ = 1.0f + (prog2 * prog2 * 0.2f);
                            logo2_squash_y_ = 1.0f + (prog2 * 0.3f);
                            logo2_stretch_x_ = 1.0f - (prog2 * 0.2f);
                            logo2_rotation_ = prog2 * 0.1f;
                        } break;

                        case AppLogoAnimationType::ROTATE_SPIRAL: {
                            float prog1 = std::min(1.0f, fade_progress_logo1);
                            float ease_t1 = easeInOutQuad(prog1);
                            logo1_scale_ = 1.0f - (ease_t1 * 0.7f);
                            logo1_rotation_ = prog1 * 6.28f;
                            logo1_squash_y_ = 1.0f;
                            logo1_stretch_x_ = 1.0f;

                            float prog2 = std::min(1.0f, fade_progress_logo2);
                            float ease_t2 = easeInOutQuad(prog2);
                            logo2_scale_ = 1.0f - (ease_t2 * 0.7f);
                            logo2_rotation_ = prog2 * 6.28f;
                            logo2_squash_y_ = 1.0f;
                            logo2_stretch_x_ = 1.0f;
                        } break;

                        case AppLogoAnimationType::BOUNCE_SQUASH: {
                            float prog1 = std::min(1.0f, fade_progress_logo1);
                            if (prog1 < 0.2f) {
                                float squash_t = prog1 / 0.2f;
                                logo1_squash_y_ = 1.0f - (squash_t * 0.3f);
                                logo1_stretch_x_ = 1.0f + (squash_t * 0.2f);
                            } else {
                                float jump_t = (prog1 - 0.2f) / 0.8f;
                                logo1_squash_y_ = 0.7f + (jump_t * 0.5f);
                                logo1_stretch_x_ = 1.2f - (jump_t * 0.2f);
                            }
                            logo1_scale_ = 1.0f + (prog1 * 0.3f);
                            logo1_rotation_ = 0.0f;

                            float prog2 = std::min(1.0f, fade_progress_logo2);
                            if (prog2 < 0.2f) {
                                float squash_t = prog2 / 0.2f;
                                logo2_squash_y_ = 1.0f - (squash_t * 0.3f);
                                logo2_stretch_x_ = 1.0f + (squash_t * 0.2f);
                            } else {
                                float jump_t = (prog2 - 0.2f) / 0.8f;
                                logo2_squash_y_ = 0.7f + (jump_t * 0.5f);
                                logo2_stretch_x_ = 1.2f - (jump_t * 0.2f);
                            }
                            logo2_scale_ = 1.0f + (prog2 * 0.3f);
                            logo2_rotation_ = 0.0f;
                        } break;
                    }
                }
            }
            break;
    }
}

void AppLogo::render() {
    // Renderizar si NO está en estado HIDDEN (incluye FADE_IN, VISIBLE, FADE_OUT)
    if (state_ != AppLogoState::HIDDEN) {
        // Renderizar LOGO1 primero (fondo), luego LOGO2 (encima)
        renderWithGeometry(1);
        renderWithGeometry(2);
    }
}

void AppLogo::updateScreenSize(int screen_width, int screen_height) {
    screen_width_ = screen_width;
    screen_height_ = screen_height;

    // ========================================================================
    // Detectar si coincide con resolución nativa o base, cambiar texturas
    // ========================================================================
    bool is_native = (screen_width == native_screen_width_ && screen_height == native_screen_height_);

    if (is_native) {
        // Cambiar a texturas nativas (F4 fullscreen)
        logo1_current_texture_ = logo1_native_texture_;
        logo1_current_width_ = logo1_native_width_;
        logo1_current_height_ = logo1_native_height_;

        logo2_current_texture_ = logo2_native_texture_;
        logo2_current_width_ = logo2_native_width_;
        logo2_current_height_ = logo2_native_height_;

        std::cout << "AppLogo: Cambiado a texturas NATIVAS" << '\n';
    } else {
        // Cambiar a texturas base (ventana redimensionable)
        logo1_current_texture_ = logo1_base_texture_;
        logo1_current_width_ = logo1_base_width_;
        logo1_current_height_ = logo1_base_height_;

        logo2_current_texture_ = logo2_base_texture_;
        logo2_current_width_ = logo2_base_width_;
        logo2_current_height_ = logo2_base_height_;

        std::cout << "AppLogo: Cambiado a texturas BASE" << '\n';
    }

    // Nota: No es necesario recalcular escalas porque las texturas están pre-escaladas
    // al tamaño exacto de pantalla. Solo renderizamos al 100% (o con deformaciones de animación).
}

// ============================================================================
// Funciones de easing para animaciones
// ============================================================================

auto AppLogo::easeOutElastic(float t) -> float {
    // Elastic easing out: bounce elástico al final
    const float C4 = (2.0f * std::numbers::pi_v<float>) / 3.0f;

    if (t == 0.0f) {
        return 0.0f;
    }
    if (t == 1.0f) {
        return 1.0f;
    }

    return (powf(2.0f, -10.0f * t) * sinf((t * 10.0f - 0.75f) * C4)) + 1.0f;
}

auto AppLogo::easeOutBack(float t) -> float {
    // Back easing out: overshoot suave al final
    const float C1 = 1.70158f;
    const float C3 = C1 + 1.0f;

    return 1.0f + (C3 * powf(t - 1.0f, 3.0f)) + (C1 * powf(t - 1.0f, 2.0f));
}

auto AppLogo::easeOutBounce(float t) -> float {
    // Bounce easing out: rebotes decrecientes (para BOUNCE_SQUASH)
    const float N1 = 7.5625f;
    const float D1 = 2.75f;

    if (t < 1.0f / D1) {
        return N1 * t * t;
    }
    if (t < 2.0f / D1) {
        t -= 1.5f / D1;
        return (N1 * t * t) + 0.75f;
    }
    if (t < 2.5f / D1) {
        t -= 2.25f / D1;
        return (N1 * t * t) + 0.9375f;
    }
    t -= 2.625f / D1;
    return (N1 * t * t) + 0.984375f;
}

auto AppLogo::easeInOutQuad(float t) -> float {
    // Quadratic easing in/out: aceleración suave (para ROTATE_SPIRAL)
    if (t < 0.5f) {
        return 2.0f * t * t;
    }
    return 1.0f - (powf((-2.0f * t) + 2.0f, 2.0f) / 2.0f);
}

// ============================================================================
// Función auxiliar para aleatorización
// ============================================================================

auto AppLogo::getRandomAnimation() -> AppLogoAnimationType {
    // Generar número aleatorio entre 0 y 3 (4 tipos de animación)
    int random_value = rand() % 4;

    switch (random_value) {
        case 0:
            return AppLogoAnimationType::ZOOM_ONLY;
        case 1:
            return AppLogoAnimationType::ELASTIC_STICK;
        case 2:
            return AppLogoAnimationType::ROTATE_SPIRAL;
        case 3:
        default:
            return AppLogoAnimationType::BOUNCE_SQUASH;
    }
}

// ============================================================================
// Renderizado con geometría (para todos los logos, con deformaciones)
// ============================================================================

void AppLogo::renderWithGeometry(int logo_index) {
    if (renderer_ == nullptr) {
        return;
    }

    // Seleccionar variables según el logo_index (1 = logo1, 2 = logo2)
    SDL_Texture* texture;
    int base_width;
    int base_height;
    float scale;
    float squash_y;
    float stretch_x;
    float rotation;

    if (logo_index == 1) {
        if (logo1_current_texture_ == nullptr) {
            return;
        }
        texture = logo1_current_texture_;
        base_width = logo1_current_width_;
        base_height = logo1_current_height_;
        scale = logo1_scale_;
        squash_y = logo1_squash_y_;
        stretch_x = logo1_stretch_x_;
        rotation = logo1_rotation_;
    } else if (logo_index == 2) {
        if (logo2_current_texture_ == nullptr) {
            return;
        }
        texture = logo2_current_texture_;
        base_width = logo2_current_width_;
        base_height = logo2_current_height_;
        scale = logo2_scale_;
        squash_y = logo2_squash_y_;
        stretch_x = logo2_stretch_x_;
        rotation = logo2_rotation_;
    } else {
        return;  // Índice inválido
    }

    // Aplicar alpha específico de cada logo (con retraso para logo2)
    int alpha = (logo_index == 1) ? logo1_alpha_ : logo2_alpha_;
    float alpha_normalized = static_cast<float>(alpha) / 255.0f;  // Convertir 0-255 → 0.0-1.0
    // NO usar SDL_SetTextureAlphaMod - aplicar alpha directamente a vértices

    // Calcular padding desde bordes derecho e inferior
    float padding_x = screen_width_ * APPLOGO_PADDING_PERCENT;
    float padding_y = screen_height_ * APPLOGO_PADDING_PERCENT;

    // Calcular esquina BASE (sin escala) para obtener centro FIJO
    // Esto asegura que el centro no se mueva cuando cambia scale/squash/stretch
    float corner_x_base = screen_width_ - base_width - padding_x;
    float corner_y_base = screen_height_ - base_height - padding_y;

    // Centro FIJO del logo (no cambia con scale/squash/stretch)
    float center_x = corner_x_base + (base_width / 2.0f);
    float center_y = corner_y_base + (base_height / 2.0f);

    // Calcular tamaño ESCALADO (para vértices)
    // (base_width y base_height ya están pre-escalados al tamaño correcto de pantalla)
    float width = base_width * scale * stretch_x;
    float height = base_height * scale * squash_y;

    // Pre-calcular seno y coseno de rotación
    float cos_rot = cosf(rotation);
    float sin_rot = sinf(rotation);

    // Crear 4 vértices del quad (centrado en center_x, center_y)
    std::array<SDL_Vertex, 4> vertices{};

    // Offset desde el centro
    float half_w = width / 2.0f;
    float half_h = height / 2.0f;

    // Vértice superior izquierdo (rotado)
    {
        float local_x = -half_w;
        float local_y = -half_h;
        float rotated_x = (local_x * cos_rot) - (local_y * sin_rot);
        float rotated_y = (local_x * sin_rot) + (local_y * cos_rot);
        vertices[0].position = {.x = center_x + rotated_x, .y = center_y + rotated_y};
        vertices[0].tex_coord = {.x = 0.0f, .y = 0.0f};
        vertices[0].color = {.r = 1.0f, .g = 1.0f, .b = 1.0f, .a = alpha_normalized};  // Alpha aplicado al vértice
    }

    // Vértice superior derecho (rotado)
    {
        float local_x = half_w;
        float local_y = -half_h;
        float rotated_x = (local_x * cos_rot) - (local_y * sin_rot);
        float rotated_y = (local_x * sin_rot) + (local_y * cos_rot);
        vertices[1].position = {.x = center_x + rotated_x, .y = center_y + rotated_y};
        vertices[1].tex_coord = {.x = 1.0f, .y = 0.0f};
        vertices[1].color = {.r = 1.0f, .g = 1.0f, .b = 1.0f, .a = alpha_normalized};  // Alpha aplicado al vértice
    }

    // Vértice inferior derecho (rotado)
    {
        float local_x = half_w;
        float local_y = half_h;
        float rotated_x = (local_x * cos_rot) - (local_y * sin_rot);
        float rotated_y = (local_x * sin_rot) + (local_y * cos_rot);
        vertices[2].position = {.x = center_x + rotated_x, .y = center_y + rotated_y};
        vertices[2].tex_coord = {.x = 1.0f, .y = 1.0f};
        vertices[2].color = {.r = 1.0f, .g = 1.0f, .b = 1.0f, .a = alpha_normalized};  // Alpha aplicado al vértice
    }

    // Vértice inferior izquierdo (rotado)
    {
        float local_x = -half_w;
        float local_y = half_h;
        float rotated_x = (local_x * cos_rot) - (local_y * sin_rot);
        float rotated_y = (local_x * sin_rot) + (local_y * cos_rot);
        vertices[3].position = {.x = center_x + rotated_x, .y = center_y + rotated_y};
        vertices[3].tex_coord = {.x = 0.0f, .y = 1.0f};
        vertices[3].color = {.r = 1.0f, .g = 1.0f, .b = 1.0f, .a = alpha_normalized};  // Alpha aplicado al vértice
    }

    // Índices para 2 triángulos
    std::array<int, 6> indices = {0, 1, 2, 2, 3, 0};

    // Renderizar con la textura del logo correspondiente
    SDL_RenderGeometry(renderer_, texture, vertices.data(), 4, indices.data(), 6);
}
