#pragma once

#include <vector>
#include <string>
#include <memory>
#include <list>
#include <filesystem>
#include <optional>

#include "lumacs/buffer.hpp" // Include the Buffer class definition
#include "lumacs/window.hpp" // For shared_ptr<Window>

#include "lumacs/i_editor_notifier.hpp"
#include "lumacs/i_window_manager.hpp"

namespace lumacs {

// class EditorCore; // Removed as we depend on interfaces now

/// @brief Manages the creation, loading, and manipulation of editor buffers.
class BufferManager {
public:
    BufferManager(IEditorNotifier& notifier, IWindowManager& window_manager);

    /// @brief Creates a new scratch buffer and makes it active in the current window.
    /// @param name The name of the new buffer (defaults to "*scratch*").
    void new_buffer(std::string name = "*scratch*");

    /// @brief Creates a buffer but does not attach it to any window.
    /// Useful for initialization or background buffer creation.
    std::shared_ptr<Buffer> create_buffer_no_window(std::string name);

    /// @brief Loads the content of a file into a new or existing buffer.
    /// If the file is already open, switches to that buffer.
    /// @param path The path to the file to load.
    /// @return True if the file was loaded successfully, false otherwise.
    bool load_file(const std::filesystem::path& path);

    /// @brief Switches the active buffer in the current window to the buffer with the given name.
    /// @param name The name of the buffer to switch to.
    /// @return True if the buffer was switched successfully, false otherwise.
    bool switch_buffer_in_window(const std::string& name);

    /// @brief Closes the buffer with the given name.
    /// If the buffer is displayed in any window, that window's buffer will be changed.
    /// Cannot close the last remaining buffer.
    /// @param name The name of the buffer to close.
    /// @return True if the buffer was closed successfully, false otherwise.
    bool close_buffer(const std::string& name);

    /// @brief Returns a shared pointer to the currently active buffer.
    /// @return The active buffer.
    [[nodiscard]] std::shared_ptr<Buffer> active_buffer();

    /// @brief Returns a shared pointer to the buffer with the given name.
    /// @param name The name of the buffer to retrieve.
    /// @return A shared pointer to the buffer, or nullptr if not found.
    [[nodiscard]] std::shared_ptr<Buffer> get_buffer_by_name(const std::string& name) const;

    /// @brief Returns a list of names of all currently managed buffers.
    [[nodiscard]] std::vector<std::string> get_buffer_names() const;
    
    /// @brief Structure containing summary information about a buffer.
    struct BufferInfo {
        std::string name;
        size_t size;
        bool modified;
        std::string mode;
        std::optional<std::filesystem::path> filepath;
    };

    /// @brief Get detailed information about all buffers.
    [[nodiscard]] std::vector<BufferInfo> get_all_buffer_info() const;

private:
    IEditorNotifier& notifier_;
    IWindowManager& window_manager_;
    std::list<std::shared_ptr<Buffer>> buffers_; // Owns the buffers
};

} // namespace lumacs
