#pragma once

#include <cstddef>  // Para size_t
#include <string>   // Para allocator, string

// --- Clase EnterName: gestor de entrada de nombre del jugador ---
class EnterName {
   public:
    // --- Constantes ---
    static constexpr size_t MAX_NAME_SIZE = 6;  // Tamaño máximo del nombre

    EnterName();
    ~EnterName() = default;

    void init(const std::string& name = "");  // Inicializa con nombre opcional (vacío por defecto)

    void incIndex();  // Incrementa el índice del carácter seleccionado en la lista
    void decIndex();  // Decrementa el índice del carácter seleccionado en la lista

    void addCharacter();         // Añade el carácter seleccionado al nombre
    void removeLastCharacter();  // Elimina el último carácter del nombre

    auto getFinalName() -> std::string;                                                                           // Obtiene el nombre final (o aleatorio si vacío)
    [[nodiscard]] auto getCurrentName() const -> std::string { return name_; }                                    // Obtiene el nombre actual en proceso
    [[nodiscard]] auto getSelectedCharacter(int offset = 0) const -> std::string;                                 // Devuelve el carácter seleccionado con offset relativo
    [[nodiscard]] auto getCarousel(int size) const -> std::string;                                                // Devuelve el carrusel de caracteres (size debe ser impar)
    [[nodiscard]] auto getSelectedIndex() const -> int { return selected_index_; }                                // Obtiene el índice del carácter seleccionado
    [[nodiscard]] auto getCharacterList() const -> const std::string& { return character_list_; }                 // Obtiene la lista completa de caracteres
    [[nodiscard]] auto nameIsFull() const -> bool { return name_.size() == MAX_NAME_SIZE; }                       // Informa de si el nombre ha alcanzado su limite
    [[nodiscard]] auto nameIsEmpty() const -> bool { return name_.empty(); }                                      // Informa de si el nombre está vacío
    [[nodiscard]] auto endCharSelected() const -> bool { return selected_index_ == character_list_.size() - 1; }  // Informa de si está seleccionado el caracter de terminar

   private:
    // --- Variables de estado ---
    std::string character_list_{"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{"};  // Lista de caracteres permitidos
    std::string name_;                                                     // Nombre en proceso
    size_t selected_index_ = 0;                                            // Índice del carácter seleccionado en "character_list_"

    [[nodiscard]] auto sanitizeName(const std::string& name) const -> std::string;  // Valida y limpia el nombre
    static auto getRandomName() -> std::string;                                     // Devuelve un nombre al azar
    void forceEndCharSelected() { selected_index_ = character_list_.size() - 1; }   // Establece como seleccionado el caracter de terminar
};