#pragma once

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

#include "utils.h"  // Para trim

// Tamaño máximo del nombre
constexpr size_t NAME_SIZE = 5;

// Clase EnterName
class EnterName {
    public:
        EnterName();
        ~EnterName() = default;

        void init(const std::string &name = "");  // Inicializa con un nombre opcional

        void incPosition();  // Incrementa la posición del carácter actual
        void decPosition();  // Decrementa la posición del carácter actual
        void incIndex();     // Incrementa el índice del carácter en la lista
        void decIndex();     // Decrementa el índice del carácter en la lista

        auto getFinalName() -> std::string;                                               // Obtiene el nombre final introducido
        [[nodiscard]] auto getCurrentName() const -> std::string { return trim(name_); }  // Obtiene el nombre actual en proceso

        [[nodiscard]] auto getPosition() const -> int { return position_; }                    // Posición actual del carácter editado
        [[nodiscard]] auto getPositionOverflow() const -> bool { return position_overflow_; }  // Indica si la posición excede el límite

    private:
        std::string character_list_;                  // Lista de caracteres permitidos
        std::string name_;                            // Nombre en proceso
        size_t position_ = 0;                         // Índice del carácter que se edita
        bool position_overflow_ = false;              // Flag para exceder límite
        std::array<int, NAME_SIZE> character_index_;  // Índices a "character_list_"

        void updateNameFromCharacterIndex();                        // Actualiza "name_" según "character_index_"
        void initCharacterIndex(const std::string &name);           // Inicializa índices desde el nombre
        [[nodiscard]] auto findIndex(char character) const -> int;  // Busca el índice de un carácter en "character_list_"
        static auto getRandomName() -> std::string;                 // Devuelve un nombre al azar
};