#pragma once

#include <SDL3/SDL.h>

#include <cstdint>  // for uint8_t
#include <vector>   // for vector
class Sprite;
class Text;
class Texture;
struct Section;

// Clase Instructions
class Instructions {
   public:
    enum class Mode : std::uint8_t {
        MANUAL,
        AUTO
    };

    Instructions(SDL_Renderer *renderer, Section *section);  // Constructor
    ~Instructions();                                         // Destructor

    Instructions(const Instructions &) = delete;
    auto operator=(const Instructions &) -> Instructions & = delete;

    void run(Mode mode);    // Bucle principal
    void start(Mode mode);  // Inicia las instrucciones (sin bucle)
    void update();          // Actualiza las variables
    void render();          // Pinta en pantalla
    void checkEvents();     // Comprueba los eventos

    [[nodiscard]] auto hasFinished() const -> bool;      // Indica si las instrucciones han terminado
    [[nodiscard]] auto isQuitRequested() const -> bool;  // Indica si se ha solicitado salir de la aplicación

   private:
    // Objetos y punteros
    SDL_Renderer *renderer_;                // El renderizador de la ventana
    std::vector<Texture *> item_textures_;  // Vector con las texturas de los items
    SDL_Event *event_handler_;              // Manejador de eventos
    SDL_Texture *backbuffer_;               // Textura para usar como backbuffer
    Sprite *sprite_;                        // Sprite con la textura de las instrucciones
    Text *text_;                            // Objeto para escribir texto
    Section *section_;                      // Estado del bucle principal para saber si continua o se sale

    // Variables
    Uint16 counter_;                       // Contador
    Uint16 counter_end_;                   // Valor final para el contador
    Uint32 ticks_;                         // Contador de ticks para ajustar la velocidad del programa
    Uint32 ticks_speed_;                   // Velocidad a la que se repiten los bucles del programa
    bool manual_quit_;                     // Indica si se quiere salir del modo manual
    Mode mode_{Instructions::Mode::AUTO};  // Modo en el que se van a ejecutar las instrucciones
    bool finished_;                        // Indica si las instrucciones han terminado
    bool quit_requested_;                  // Indica si se ha solicitado salir de la aplicación

    void checkInput();  // Comprueba las entradas
};
