#include "enter_name.h"
#include <stddef.h> // Para size_t
#include "utils.h"  // Para trim

// Constructor
EnterName::EnterName()
    : character_list_(" ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."),
      character_index_{0} {}

// Inicializa el objeto
void EnterName::init(const std::string &name)
{
    // No se pasa ningún nombre
    if (name.empty())
    {
        name_ = "A";
        position_ = 0;
        position_overflow_ = false;
    }
    // Se pasa un nombre
    else
    {
        name_ = name;
        position_ = name_.length();
        position_overflow_ = position_ >= NAME_SIZE ? true : false;
    }

    // Inicializa el vector de indices con el nombre y espacios
    initCharacterIndex(name_);
}

// Incrementa la posición
void EnterName::incPosition()
{
    if (position_overflow_)
    {
        // Si ya estamos en overflow, no incrementamos más.
        return;
    }

    ++position_;

    if (position_ >= NAME_SIZE)
    {
        position_ = NAME_SIZE;     // Mantenemos en el índice máximo válido.
        position_overflow_ = true; // Activamos el flag de overflow.
    }
    else if (position_ > 0) // No es necesario verificar position_ < MAX_NAME_LENGHT
    {
        // Copiamos el índice del carácter anterior si es posible.
        character_index_[position_] = character_index_[position_ - 1];
    }
    else
    {
        // Si position_ es 0, inicializamos el carácter actual.
        character_index_[position_] = 0;
    }

    updateNameFromCharacterIndex();
}

// Decrementa la posición
void EnterName::decPosition()
{
    if (position_overflow_)
    {
        // Si estaba en overflow, lo desactivamos y mantenemos position_ en el máximo.
        position_overflow_ = false;
        position_ = NAME_SIZE - 1;
    }
    else
    {
        if (position_ > 0)
        {
            --position_;

            // Limpiamos el carácter siguiente si el índice es válido.
            if (position_ + 1 < NAME_SIZE)
            {
                character_index_[position_ + 1] = 0;
            }
        }
        else
        {
            // Si position_ es 0, aseguramos que no vaya a ser negativo y limpiamos el carácter actual.
            position_ = 0;
            character_index_[position_] = 0;
        }

        // Si position_ es menor que NAME_LENGHT, aseguramos que el overflow esté desactivado.
        if (position_ < NAME_SIZE)
        {
            position_overflow_ = false;
        }
    }

    updateNameFromCharacterIndex();
}

// Incrementa el índice
void EnterName::incIndex()
{
    if (position_overflow_)
    {
        return;
    }

    ++character_index_[position_];
    if (character_index_[position_] >= static_cast<int>(character_list_.size()))
    {
        character_index_[position_] = 0;
    }
    updateNameFromCharacterIndex();
}

// Decrementa el índice
void EnterName::decIndex()
{
    if (position_overflow_)
    {
        return;
    }

    --character_index_[position_];
    if (character_index_[position_] < 0)
    {
        character_index_[position_] = character_list_.size() - 1;
    }
    updateNameFromCharacterIndex();
}

// Actualiza el nombre a partir de la lista de índices
void EnterName::updateNameFromCharacterIndex()
{
    name_.clear();
    for (size_t i = 0; i < NAME_SIZE; ++i)
    {
        name_.push_back(character_list_[character_index_[i]]);
    }
    name_ = trim(name_);
}

// Actualiza la variable
void EnterName::initCharacterIndex(const std::string &name)
{
    // Rellena de espacios
    for (size_t i = 0; i < NAME_SIZE; ++i)
    {
        character_index_[i] = 0;
    }

    // Coloca los índices en función de los caracteres que forman el nombre
    for (size_t i = 0; i < name.substr(0, NAME_SIZE).size(); ++i)
    {
        character_index_[i] = findIndex(name.at(i));
    }
}

// Encuentra el indice de un caracter en "character_list_"
int EnterName::findIndex(char character) const
{
    for (size_t i = 0; i < character_list_.size(); ++i)
    {
        if (character == character_list_.at(i))
        {
            return i;
        }
    }
    return 0;
}