#pragma once

#include <functional>     // Para function
#include <string>         // Para string
#include <unordered_map>  // Para unordered_map
#include <vector>         // Para vector

// Definición de un comando de consola (metadatos cargados desde YAML)
struct CommandDef {
    std::string keyword;
    std::string handler_id;
    std::string category;
    std::string description;
    std::string usage;
    bool instant{false};
    bool hidden{false};
    bool debug_only{false};
    bool help_hidden{false};
    bool dynamic_completions{false};
    std::vector<std::string> scopes;  // Ámbitos: "global", "game", "editor", "debug"
    std::unordered_map<std::string, std::vector<std::string>> completions;
};

// Tipo de función handler para comandos
using CommandHandler = std::function<std::string(const std::vector<std::string>& args)>;

// Proveedor de completions dinámicas: devuelve las opciones para TAB en UPPERCASE
using DynamicCompletionProvider = std::function<std::vector<std::string>()>;

// Registro de comandos: une metadatos YAML con handlers C++
class CommandRegistry {
   public:
    // Carga los metadatos de comandos desde un archivo YAML y registra los handlers
    void load(const std::string& yaml_path);

    // Búsqueda y ejecución
    [[nodiscard]] auto findCommand(const std::string& keyword) const -> const CommandDef*;
    auto execute(const std::string& keyword, const std::vector<std::string>& args) const -> std::string;

    // Generación de ayuda (auto-generada desde los metadatos)
    [[nodiscard]] auto generateTerminalHelp() const -> std::string;
    [[nodiscard]] auto generateConsoleHelp() const -> std::string;

    // Scope activo (filtra comandos visibles en help y tab completion)
    void setScope(const std::string& scope) { active_scope_ = scope; }
    [[nodiscard]] auto getScope() const -> const std::string& { return active_scope_; }

    // TAB completion
    [[nodiscard]] auto getCompletions(const std::string& path) const -> std::vector<std::string>;
    [[nodiscard]] auto getVisibleKeywords() const -> std::vector<std::string>;

   private:
    std::vector<CommandDef> commands_;
    std::unordered_map<std::string, CommandHandler> handlers_;
    std::unordered_map<std::string, std::vector<std::string>> completions_map_;
    std::unordered_map<std::string, DynamicCompletionProvider> dynamic_providers_;
    std::string active_scope_;  // Scope activo ("" = sin filtro, muestra todo)

    void registerHandlers();
    [[nodiscard]] auto isCommandVisible(const CommandDef& cmd) const -> bool;
    [[nodiscard]] static auto generateKeysHelp(const std::string& scope_filter) -> std::string;
    [[nodiscard]] auto buildHelp(const std::vector<std::string>& args) const -> std::string;  // Implementació del handler "cmd_help"
};
