#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/operators.h>
#include "fast_tree.h"

namespace py = pybind11;

PYBIND11_MODULE(_cutysoup, m) {
    m.doc() = "CutySoup - Fast HTML parsing library";

    // FastTree class
    py::class_<cutysoup::FastTree, std::shared_ptr<cutysoup::FastTree>>(m, "Tree")
        .def(py::init<const std::string&>())
        .def("get_root", &cutysoup::FastTree::get_root, 
             "Get the root node of the HTML tree")
        .def("find_all_by_tag", &cutysoup::FastTree::find_all_by_tag,
             "Find all elements with the specified tag name")
        .def("find_all_by_class", &cutysoup::FastTree::find_all_by_class,
             "Find all elements with the specified class name")  
        .def("find_all_by_id", &cutysoup::FastTree::find_all_by_id,
             "Find all elements with the specified ID")
        .def("select", &cutysoup::FastTree::select,
             "Select elements using CSS selector")
        .def("select_one", &cutysoup::FastTree::select_one,
             "Select first element using CSS selector")
        .def("select_by_complex_selector", &cutysoup::FastTree::select_by_complex_selector,
             "Select elements using advanced C++ CSS selector engine")
        .def("matches_css_selector", &cutysoup::FastTree::matches_css_selector,
             "Check if a node matches a CSS selector")
        
        // MaxCpp Phase 35: C++ bulk find operations
        .def("bulk_find_all", &cutysoup::FastTree::bulk_find_all,
             py::arg("name") = "", py::arg("attrs") = std::map<std::string, std::string>(), py::arg("recursive") = true,
             "Find all elements using C++ bulk operations for maximum performance")
        .def("bulk_find", &cutysoup::FastTree::bulk_find,
             py::arg("name") = "", py::arg("attrs") = std::map<std::string, std::string>(), py::arg("recursive") = true,
             "Find first element using C++ bulk operations for maximum performance")
        .def("bulk_find_all_strings", &cutysoup::FastTree::bulk_find_all_strings,
             "Find all string/text nodes using C++ operations")
        .def("bulk_find_parents", &cutysoup::FastTree::bulk_find_parents,
             py::arg("node"), py::arg("name") = "", py::arg("attrs") = std::map<std::string, std::string>(),
             "Find parent elements matching criteria using C++ operations")
        .def("extract_all_text_by_tag", &cutysoup::FastTree::extract_all_text_by_tag,
             "Extract text from all elements with specified tag")
        .def("extract_all_hrefs", &cutysoup::FastTree::extract_all_hrefs,
             "Extract all href attributes from anchor tags")
        .def("extract_all_src", &cutysoup::FastTree::extract_all_src,
             "Extract all src attributes from img tags")
        .def("get_node_count", &cutysoup::FastTree::get_node_count,
             "Get total number of nodes in the tree")
        
        // Advanced indexing methods for large documents  
        .def("find_by_attribute", &cutysoup::FastTree::find_by_attribute,
             py::arg("attr_name"), py::arg("value"),
             "Find elements by attribute name and value using advanced indexing")
        .def("find_by_text_content", &cutysoup::FastTree::find_by_text_content,
             py::arg("text"),
             "Find elements by their immediate text content using advanced indexing")
        .def("get_nth_element", &cutysoup::FastTree::get_nth_element,
             py::arg("index"),
             "Get the nth element from the indexed elements list")
        
        // Performance and indexing statistics
        .def("get_indexed_node_count", &cutysoup::FastTree::get_indexed_node_count,
             "Get number of indexed nodes")
        .def("get_index_build_time", &cutysoup::FastTree::get_index_build_time,
             "Get time taken to build indexes (in seconds)")
        .def("are_indexes_built", &cutysoup::FastTree::are_indexes_built,
             "Check if indexes have been built");

    // FastNode class  
    py::class_<cutysoup::FastNode, std::shared_ptr<cutysoup::FastNode>>(m, "Node")
        .def("get_name", &cutysoup::FastNode::get_name,
             "Get the tag name of this node")
        .def("get_text", &cutysoup::FastNode::get_text,
             "Get the text content of this node and its descendants")
        
        // MaxCpp Phase 32: Advanced C++ text processing methods
        .def("get_text_with_separator", &cutysoup::FastNode::get_text_with_separator,
             py::arg("separator"),
             "Get text content with custom separator between parts")
        .def("get_text_stripped", &cutysoup::FastNode::get_text_stripped,
             "Get text content with leading/trailing whitespace removed")
        .def("get_text_with_separator_stripped", &cutysoup::FastNode::get_text_with_separator_stripped,
             py::arg("separator"),
             "Get text content with separator and whitespace trimming")
        .def("get_strings", &cutysoup::FastNode::get_strings,
             "Get all string contents as vector (C++ bulk operation)")
        .def("get_stripped_strings", &cutysoup::FastNode::get_stripped_strings,
             "Get all non-empty stripped string contents (C++ bulk operation)")
        .def("get_direct_text", &cutysoup::FastNode::get_direct_text,
             "Get only direct text content (not from descendants)")
        
        // MaxCpp Phase 33: C++ Tree Navigation Bulk Operations
        .def("get_all_descendants", &cutysoup::FastNode::get_all_descendants,
             "Get all descendant elements as vector (C++ bulk operation)")
        .def("get_all_descendants_with_text", &cutysoup::FastNode::get_all_descendants_with_text,
             "Get all descendants including text nodes as vector (C++ bulk operation)")
        .def("get_all_parents", &cutysoup::FastNode::get_all_parents,
             "Get all parent elements as vector (C++ bulk operation)")
        .def("get_all_next_siblings", &cutysoup::FastNode::get_all_next_siblings,
             "Get all next sibling elements as vector (C++ bulk operation)")
        .def("get_all_previous_siblings", &cutysoup::FastNode::get_all_previous_siblings,
             "Get all previous sibling elements as vector (C++ bulk operation)")
        .def("get_all_next_siblings_including_text", &cutysoup::FastNode::get_all_next_siblings_including_text,
             "Get all next siblings including text as vector (C++ bulk operation)")
        .def("get_all_previous_siblings_including_text", &cutysoup::FastNode::get_all_previous_siblings_including_text,
             "Get all previous siblings including text as vector (C++ bulk operation)")
        .def("get_attributes", &cutysoup::FastNode::get_attributes,
             "Get all attributes as a dictionary")
        .def("get_attribute", &cutysoup::FastNode::get_attribute,
             "Get the value of a specific attribute")
        .def("has_attribute", &cutysoup::FastNode::has_attribute,
             "Check if node has a specific attribute")
        .def("get_parent", &cutysoup::FastNode::get_parent,
             "Get the parent node")
        .def("get_children", &cutysoup::FastNode::get_children,
             "Get all child nodes")
        .def("get_next_sibling", &cutysoup::FastNode::get_next_sibling,
             "Get the next sibling node")
        .def("get_previous_sibling", &cutysoup::FastNode::get_previous_sibling,
             "Get the previous sibling node")
        .def("is_text", &cutysoup::FastNode::is_text,
             "Check if this is a text node")
        .def("is_element", &cutysoup::FastNode::is_element,
             "Check if this is an element node")
        .def("find_descendants_by_tag", &cutysoup::FastNode::find_descendants_by_tag,
             "Find all descendant elements with specified tag")
        .def("select", &cutysoup::FastNode::select,
             "Select elements using CSS selector within this node")
        .def("select_one", &cutysoup::FastNode::select_one,
             "Select first element using CSS selector within this node")
        
        // MaxCpp Phase 35: FastNode bulk find operations
        .def("node_find_all", &cutysoup::FastNode::node_find_all,
             py::arg("name") = "", py::arg("attrs") = std::map<std::string, std::string>(), py::arg("recursive") = true,
             "Find all elements from this node using C++ bulk operations")
        .def("node_find", &cutysoup::FastNode::node_find,
             py::arg("name") = "", py::arg("attrs") = std::map<std::string, std::string>(), py::arg("recursive") = true,
             "Find first element from this node using C++ bulk operations");

    // Version info
    m.attr("__version__") = "1.0.0-fast";
}