/**
 * @file camera_driver_node.h
 * @brief V4L2 相机驱动节点 - 头文件
 * 
 * 使用 V4L2 直接读取 USB 摄像头 MJPEG 流，支持定时拍照和服务触发拍照
 * 
 * @author flowzl
 * @date 2026-01-19
 */

#pragma once

#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/nav_sat_fix.hpp>
#include <thread>
#include <atomic>
#include <chrono>
#include <vector>
#include <fstream>
#include <filesystem>
#include <iomanip>
#include <sstream>
#include <mutex>
#include <string>

// V4L2 includes
#include <linux/videodev2.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/stat.h>

// 服务定义
#include "skylink_bridge/srv/trigger_capture.hpp"

// OpenCV for thumbnail generation
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>

// HTTP server
#include "skylink_bridge/httplib.h"

/**
 * @class CameraDriverNode
 * @brief V4L2 相机驱动 ROS 2 节点
 */
class CameraDriverNode : public rclcpp::Node {
public:
    /**
     * @brief 构造函数
     */
    CameraDriverNode();
    
    /**
     * @brief 析构函数
     */
    ~CameraDriverNode();

    // 设备信息查询接口
    const std::string& device_path() const { return video_device_; }
    const std::string& device_name() const { return device_name_; }
    uint16_t image_width() const { return static_cast<uint16_t>(image_width_); }
    uint16_t image_height() const { return static_cast<uint16_t>(image_height_); }
    float target_fps() const { return static_cast<float>(target_framerate_); }
    uint32_t pixel_format_fourcc() const { return pixel_format_fourcc_; }
    float current_fps() const { return current_fps_; }
    uint32_t total_frames() const { return frame_counter_; }
    uint32_t total_photos() const { return total_photos_saved_.load(); }
    
private:
    // ========================================================================
    // V4L2 结构
    // ========================================================================
    struct Buffer {
        void *start;
        size_t length;
    };

    // ========================================================================
    // 成员变量
    // ========================================================================
    
    // V4L2 members
    int fd_ = -1;
    std::vector<Buffer> buffers_;
    
    /** 摄像头参数 */
    std::string video_device_;
    std::string device_name_{"Unknown"};
    double target_framerate_;
    int image_width_;
    int image_height_;
    bool enable_fps_stats_;
    
    /** GPS 订阅 */
    std::string gps_topic_;
    rclcpp::Subscription<sensor_msgs::msg::NavSatFix>::SharedPtr gps_subscription_;
    sensor_msgs::msg::NavSatFix latest_gps_fix_;
    std::mutex gps_mutex_;
    bool has_gps_fix_ = false;
    
    /** 服务接口 */
    rclcpp::Service<skylink_bridge::srv::TriggerCapture>::SharedPtr trigger_service_;
    
    /** HTTP 服务器相关 */
    std::thread http_server_thread_;
    std::atomic<bool> http_server_running_{false};
    int http_port_ = 8080;
    bool http_enabled_ = true;
    
    /** 捕获线程 */
    std::thread capture_thread_;
    std::atomic<bool> capturing_{false};
    
    /** 定时拍照相关 */
    rclcpp::TimerBase::SharedPtr capture_timer_;
    bool capture_enabled_;      // 是否启用定时拍照
    double capture_interval_;  // 拍照间隔（秒）
    int photo_count_per_batch_;  // 每批拍照数量
    int current_photo_index_;  // 当前批次中的照片索引
    std::atomic<bool> is_capturing_{false};  // 是否正在拍照
    std::mutex capture_mutex_;  // 拍照互斥锁
    
    /** 照片保存 */
    std::string save_dir_;
    std::atomic<uint32_t> total_photos_saved_{0};  // 总照片数
    
    /** 传输模式 */
    enum class TransmissionMode {
        ORIGINAL,    // 原图
        THUMBNAIL    // 缩略图
    };
    TransmissionMode transmission_mode_ = TransmissionMode::ORIGINAL;
    int thumbnail_width_ = 640;   // 缩略图宽度
    int thumbnail_height_ = 480;   // 缩略图高度
    
    /** 统计信息 */
    uint32_t frame_counter_ = 0;
    std::chrono::system_clock::time_point last_stats_time_;
    float current_fps_ = 0.0f;
    uint32_t pixel_format_fourcc_ = V4L2_PIX_FMT_MJPEG;
    
    /** 最新帧数据缓存（用于拍照） */
    std::vector<uint8_t> latest_frame_data_;
    std::mutex frame_data_mutex_;
    std::atomic<bool> has_frame_data_{false};
    
    // ========================================================================
    // 私有方法
    // ========================================================================
    
    // xioctl helper
    static int xioctl(int fh, int request, void *arg);

    /**
     * @brief 关闭设备
     */
    void close_device();

    /**
     * @brief 释放内存映射
     */
    void uninit_device();

    /**
     * @brief 停止流
     */
    void stop_capturing();

    /**
     * @brief 初始化摄像头
     */
    bool init_camera();
    
    /**
     * @brief 捕获工作线程（持续获取帧数据并缓存）
     */
    void capture_worker();
    
    /**
     * @brief 拍照并保存
     * @param mode 传输模式（原图或缩略图）
     */
    void capture_photo(TransmissionMode mode = TransmissionMode::ORIGINAL);
    
    /**
     * @brief 生成缩略图
     * @param original_data 原始JPEG数据
     * @return 缩略图JPEG数据
     */
    std::vector<uint8_t> generate_thumbnail(const std::vector<uint8_t>& original_data);
    
    /**
     * @brief 启动批量拍照
     * @param duration 总时间（秒）
     * @param count 拍照数量
     * @param interval 时间间隔（秒）
     * @param mode 传输模式
     */
    void start_batch_capture(double duration, int count, double interval, TransmissionMode mode);
    
    /**
     * @brief 服务回调函数
     */
    void service_callback(
        const std::shared_ptr<skylink_bridge::srv::TriggerCapture::Request> request,
        std::shared_ptr<skylink_bridge::srv::TriggerCapture::Response> response);
    
    /**
     * @brief 报告统计信息 (Legacy)
     */
    void report_stats();
    
    // ========================================================================
    // HTTP 服务器方法
    // ========================================================================
    
    /**
     * @brief 启动 HTTP 服务器
     */
    void start_http_server();
    
    /**
     * @brief 停止 HTTP 服务器
     */
    void stop_http_server();
    
    /**
     * @brief HTTP 服务器工作线程
     */
    void http_server_worker();
    
    /**
     * @brief 处理触发拍照 API 请求
     * @param req HTTP 请求
     * @param res HTTP 响应
     */
    void handle_trigger_capture_api(const httplib::Request& req, httplib::Response& res);
    
    /**
     * @brief 处理状态查询 API 请求
     * @param req HTTP 请求
     * @param res HTTP 响应
     */
    void handle_status_api(const httplib::Request& req, httplib::Response& res);
    
    /**
     * @brief 简单的 JSON 解析辅助函数 - double 特化
     */
    double parse_json_value_double(const std::string& json_str, const std::string& key, double default_value);
    
    /**
     * @brief 简单的 JSON 解析辅助函数 - int 特化
     */
    int parse_json_value_int(const std::string& json_str, const std::string& key, int default_value);
};
