#pragma once

#include <functional>
#include <optional>
#include <unordered_map> // For std::unordered_map

#include "lumacs/command_system.hpp" // Include for CommandResult definition
#include "lumacs/history_manager.hpp" // New include
#include "lumacs/minibuffer_mode_hash.hpp" // Include for MinibufferMode hash specialization
#include "lumacs/minibuffer_mode.hpp" // Include for MinibufferMode enum definition
#include "lumacs/completion_common.hpp" // Include for CompletionCandidate struct

namespace lumacs {

// Forward declarations to avoid circular dependencies
class EditorCore; 
class LuaApi;
class CompletionSystem; // Forward declaration

/// @brief Manages the state and logic for the minibuffer, independent of the UI.
class MinibufferManager {
public:
    MinibufferManager(EditorCore& core, LuaApi& lua_api, CompletionSystem& completion_system);

    /// @brief Sets the minibuffer into a specific mode and displays a prompt.
    void activate_minibuffer(MinibufferMode mode, const std::string& prompt, 
                             std::function<void(const std::string&)> on_submit,
                             std::function<void()> on_cancel = nullptr);

    /// @brief Deactivates the minibuffer and clears its state.
    void deactivate_minibuffer();

    /// @brief Handles a key event when the minibuffer is active.
    /// @return True if the key was handled, false otherwise.
    bool handle_key_event(const std::string& key_name);

    /// @brief Returns the current prompt string for display.
    std::string get_prompt() const;

    /// @brief Returns the current input buffer content for display.
    std::string get_input_buffer() const;

    /// @brief Returns the current cursor position within the input buffer.
    size_t get_cursor_position() const;

    /// @brief Returns whether the minibuffer is currently active.
    bool is_active() const { return current_mode_ != MinibufferMode::None; }

    /// @brief Returns the current minibuffer mode.
    MinibufferMode get_current_mode() const { return current_mode_; }

    /// @brief Sets the input buffer content directly.
    void set_input_buffer(const std::string& input);

    // History navigation
    void history_previous();
    void history_next();

    // Completion related methods
    void update_completion_candidates();
    std::vector<CompletionCandidate> get_completion_candidates() const;
    std::optional<std::string> get_current_completion() const;
    void complete(); // For tab completion

    // ISearch related methods and state
    bool is_isearch_active() const { return isearch_active_; }
    std::optional<Range> get_isearch_match_range() const { return isearch_match_range_; }
    bool is_isearch_failed() const { return isearch_failed_; }

    /// @brief Parses a command string and executes the corresponding command.

    /// @brief Parses a command string and executes the corresponding command.
    /// @param command_line The string containing the command name and its arguments.
    /// @return The result of the command execution.
    CommandResult parse_and_execute_command_string(const std::string& command_line); // Made public

private:
    EditorCore& core_;
    [[maybe_unused]] LuaApi& lua_api_; // Reserved for future Lua integration
    CompletionSystem& completion_system_;

    MinibufferMode current_mode_ = MinibufferMode::None;
    std::string prompt_text_;
    std::string input_buffer_;
    std::function<void(const std::string&)> on_submit_callback_;
    std::function<void()> on_cancel_callback_;
    size_t cursor_position_ = 0; // Tracks the current cursor position within input_buffer_

    // History
    std::unordered_map<MinibufferMode, HistoryManager> histories_;
    HistoryManager* current_history_ = nullptr; // Pointer to the active history manager

    // Completion
    std::vector<CompletionCandidate> completion_candidates_;
    size_t completion_index_ = 0;

    // ISearch state
    bool isearch_active_ = false;
    std::optional<Range> isearch_match_range_;
    bool isearch_failed_ = false;
    std::optional<Position> isearch_start_cursor_; // Cursor position when ISearch started
    bool isearch_direction_forward_ = true; // True for forward search, false for backward
    std::string last_search_query_; // Last successful or attempted query

    // ISearch control methods
    void start_isearch(bool forward);
    void update_isearch(const std::string& query);
    void next_isearch_match();
    void previous_isearch_match();
    void stop_isearch();

    /// @brief Helper to add current input to history if it's new.
    void add_to_history();
};

} // namespace lumacs