#include "common/utils.hpp"
#include "nodes/base/base.hpp"
#include "nodes/draw/drawNode.hpp"
#include "nodes/draw/position.hpp"
#include <opencv2/opencv.hpp>
#include <chrono>


namespace Node
{

static std::tuple<int, int, int> getFontSize(const std::string& text)
{
    int baseline = 0;
    cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 2, &baseline);
    // std::cout << textSize << std::endl;
    return std::make_tuple(textSize.width, textSize.height, baseline);
}

void DrawNode::work() 
{
    printf("DrawNode %s\n", name_.c_str());
    while (running_)
    {
        bool has_data = false;
        for (auto& input_buffer : input_buffers_)
        {
            std::shared_ptr<meta::MetaData> metaData;
            if (!input_buffer.second->try_pop(metaData))
            {
                continue;
            }
            has_data = true;
            // printf("Node %s get data from %s\n", name_.c_str(), input_buffer.first.c_str());
            cv::Mat image = metaData->image.clone();
            int image_width = image.cols;
            int image_height = image.rows;
            PositionManager<float> pm(getFontSize);
            for (auto& box : metaData->boxes)
            {
                cv::rectangle(image, cv::Point(box.left, box.top), cv::Point(box.right, box.bottom), cv::Scalar(0, 255, 0), 2);

                std::tuple<int, int, int, int> pbox = std::make_tuple(box.left, box.top, box.right, box.bottom);
                int x, y;
                std::tie(x, y) = pm.selectOptimalPosition(pbox, image_width, image_height, box.label);
                std::string text = str_format("%s %.2f id=%d", box.label.c_str(), box.score, b.track_id);
                cv::putText(image, text, cv::Point(x, y), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0), 2);
            }
            metaData->draw_image = image;
            for (auto& output_buffer : output_buffers_)
            {
                // printf("Node %s push data to %s\n", name_.c_str(), output_buffer.first.c_str());
                output_buffer.second->push(metaData);
            }
        }
        if (!has_data) {
            // printf("draw wait data\n");
            std::unique_lock<std::mutex> lock(mutex_);
            cond_var_->wait_for(lock, std::chrono::milliseconds(100), [this] {
                return !running_;  // 等待时检查退出条件
            });
        }
    }
}

}
