#pragma once

#include <SDL3/SDL_render.h>  // for SDL_Renderer

#include <memory>  // for unique_ptr, shared_ptr

#include "defines.hpp"  // for AppMode

class Texture;
class Sprite;

// Estados de la máquina de estados del logo
enum class AppLogoState {
    HIDDEN,   // Logo oculto, esperando APPLOGO_DISPLAY_INTERVAL
    FADE_IN,  // Apareciendo (alpha 0 → 255)
    VISIBLE,  // Completamente visible, esperando APPLOGO_DISPLAY_DURATION
    FADE_OUT  // Desapareciendo (alpha 255 → 0)
};

// Tipo de animación de entrada/salida
enum class AppLogoAnimationType {
    ZOOM_ONLY,      // A: Solo zoom simple (120% → 100% → 120%)
    ELASTIC_STICK,  // B: Zoom + deformación elástica tipo "pegatina"
    ROTATE_SPIRAL,  // C: Rotación en espiral (entra girando, sale girando)
    BOUNCE_SQUASH   // D: Rebote con aplastamiento (cae rebotando, salta)
};

class AppLogo {
    public:
        AppLogo() = default;
        ~AppLogo();  // Necesario para liberar las 4 texturas SDL

        // Inicializar textura y sprite del logo
        bool initialize(SDL_Renderer* renderer, int screen_width, int screen_height);

        // Actualizar temporizadores y estado de visibilidad
        void update(float delta_time, AppMode current_mode);

        // Renderizar logo si está visible
        void render();

        // Actualizar tamaño de pantalla (reposicionar logo)
        void updateScreenSize(int screen_width, int screen_height);

    private:
        // ====================================================================
        // Texturas pre-escaladas (4 texturas: 2 logos × 2 resoluciones)
        // ====================================================================
        SDL_Texture* logo1_base_texture_ = nullptr;    // Logo1 para resolución base
        SDL_Texture* logo1_native_texture_ = nullptr;  // Logo1 para resolución nativa (F4)
        SDL_Texture* logo2_base_texture_ = nullptr;    // Logo2 para resolución base
        SDL_Texture* logo2_native_texture_ = nullptr;  // Logo2 para resolución nativa (F4)

        // Dimensiones pre-calculadas para cada textura
        int logo1_base_width_ = 0, logo1_base_height_ = 0;
        int logo1_native_width_ = 0, logo1_native_height_ = 0;
        int logo2_base_width_ = 0, logo2_base_height_ = 0;
        int logo2_native_width_ = 0, logo2_native_height_ = 0;

        // Texturas actualmente en uso (apuntan a base o native según resolución)
        SDL_Texture* logo1_current_texture_ = nullptr;
        SDL_Texture* logo2_current_texture_ = nullptr;
        int logo1_current_width_ = 0, logo1_current_height_ = 0;
        int logo2_current_width_ = 0, logo2_current_height_ = 0;

        // Resoluciones conocidas
        int base_screen_width_ = 0, base_screen_height_ = 0;      // Resolución inicial
        int native_screen_width_ = 0, native_screen_height_ = 0;  // Resolución nativa (F4)

        // ====================================================================
        // Variables COMPARTIDAS (sincronización de ambos logos)
        // ====================================================================
        AppLogoState state_ = AppLogoState::HIDDEN;  // Estado actual de la máquina de estados
        float timer_ = 0.0f;                         // Contador de tiempo para estado actual

        // Alpha INDEPENDIENTE para cada logo (Logo 2 con retraso)
        int logo1_alpha_ = 0;  // Alpha de Logo 1 (0-255)
        int logo2_alpha_ = 0;  // Alpha de Logo 2 (0-255, con retraso)

        // Animación COMPARTIDA (misma para ambos logos, misma entrada y salida)
        AppLogoAnimationType current_animation_ = AppLogoAnimationType::ZOOM_ONLY;

        // Variables de deformación INDEPENDIENTES para logo1
        float logo1_scale_ = 1.0f;      // Escala actual de logo1 (1.0 = 100%)
        float logo1_squash_y_ = 1.0f;   // Factor de aplastamiento vertical logo1
        float logo1_stretch_x_ = 1.0f;  // Factor de estiramiento horizontal logo1
        float logo1_rotation_ = 0.0f;   // Rotación en radianes logo1

        // Variables de deformación INDEPENDIENTES para logo2
        float logo2_scale_ = 1.0f;      // Escala actual de logo2 (1.0 = 100%)
        float logo2_squash_y_ = 1.0f;   // Factor de aplastamiento vertical logo2
        float logo2_stretch_x_ = 1.0f;  // Factor de estiramiento horizontal logo2
        float logo2_rotation_ = 0.0f;   // Rotación en radianes logo2

        int screen_width_ = 0;   // Ancho de pantalla (para centrar)
        int screen_height_ = 0;  // Alto de pantalla (para centrar)

        // Tamaño base del logo (calculado una vez)
        float base_width_ = 0.0f;
        float base_height_ = 0.0f;

        // SDL renderer (necesario para renderizado con geometría)
        SDL_Renderer* renderer_ = nullptr;

        // Métodos privados auxiliares
        void updateLogoPosition();                // Centrar ambos logos en pantalla (superpuestos)
        void renderWithGeometry(int logo_index);  // Renderizar logo con vértices deformados (1 o 2)

        // Funciones de easing
        static float easeOutElastic(float t);  // Elastic bounce out
        static float easeOutBack(float t);     // Overshoot out
        static float easeOutBounce(float t);   // Bounce easing (para BOUNCE_SQUASH)
        static float easeInOutQuad(float t);   // Quadratic easing (para ROTATE_SPIRAL)

        // Función auxiliar para elegir animación aleatoria
        static AppLogoAnimationType getRandomAnimation();
};
