#pragma once

#include <string>
#include <memory>
#include <vector>
#include <map>
#include <mutex>
#include <unordered_map>
#include "gumbo.h"

namespace cutysoup {

class Node;
class BulkOperations;
class ZeroContextBatch;

class Tree {
public:
    explicit Tree(const std::string& html);
    ~Tree();
    
    std::shared_ptr<Node> get_root() const;
    const GumboOutput* get_output() const { return output_; }
    
    // Bulk operations for ultra-fast searches
    BulkOperations* get_bulk_operations() const { return bulk_ops_.get(); }
    
    // Zero-context batch operations for ultimate performance
    ZeroContextBatch* get_zero_context_batch() const { return zero_context_.get(); }
    
    // Tree modification methods
    std::shared_ptr<Node> create_element(const std::string& tag_name, 
                                        const std::map<std::string, std::string>& attributes = {});
    
    // Advanced indexing methods for large documents (via BulkOperations)
    std::vector<std::shared_ptr<Node>> find_by_attribute(const std::string& attr_name, const std::string& value);
    std::vector<std::shared_ptr<Node>> find_by_text_content(const std::string& text);
    std::shared_ptr<Node> get_nth_element(size_t index);
    
    // Performance metrics
    double get_index_build_time() const;
    size_t get_indexed_element_count() const;

    // Node wrapper caching for fast repeated traversal/materialization.
    std::shared_ptr<Node> get_or_create_node(GumboNode* gumbo_node) const;

private:
    GumboOutput* output_;
    std::shared_ptr<Node> root_node_;
    std::unique_ptr<BulkOperations> bulk_ops_;
    std::unique_ptr<ZeroContextBatch> zero_context_;
    mutable std::mutex node_cache_mutex_;
    mutable std::unordered_map<GumboNode*, std::weak_ptr<Node>> node_cache_;
    
    // Helper methods for tree modification
    GumboNode* create_gumbo_element(const std::string& tag_name, 
                                   const std::map<std::string, std::string>& attributes);
};

} // namespace cutysoup
