/**
 * @file GroundReceiver.cpp
 * @brief SkyLink Qt 地面站 - UDP 接收和数据重组实现
 * 
 * @author flowzl
 * @date 2026-01-19
 */

#include "GroundReceiver.h"
#include <QTimer>
#include <QHostAddress>
#include <QDateTime>
#include <cstring>
#include <algorithm>
#include <iostream>

GroundReceiver::GroundReceiver(QObject* parent, uint16_t port)
    : QObject(parent), listen_port_(port), last_complete_frame_id_(0) {
    
    // 创建 UDP 套接字
    udp_socket_ = std::make_unique<QUdpSocket>(this);
    
    // 连接信号
    connect(udp_socket_.get(), &QUdpSocket::readyRead,
            this, &GroundReceiver::on_udp_read_ready);
    
    // 定时器用于清理超时帧
    QTimer* cleanup_timer = new QTimer(this);
    connect(cleanup_timer, &QTimer::timeout,
            this, &GroundReceiver::on_cleanup_timeout);
    cleanup_timer->start(1000);  // 每秒清理一次
    
    stats_.last_stats_time = QDateTime::currentMSecsSinceEpoch();
}

GroundReceiver::~GroundReceiver() {
    stop();
}

void GroundReceiver::start() {
    if (!udp_socket_->bind(QHostAddress::AnyIPv4, listen_port_)) {
        emit error(QString("无法绑定 UDP 端口 %1: %2")
                  .arg(listen_port_).arg(udp_socket_->errorString()));
        return;
    }
    
    std::cout << "✓ UDP 接收器已启动，监听端口: " << listen_port_ << std::endl;
}

void GroundReceiver::stop() {
    if (udp_socket_) {
        udp_socket_->close();
    }
}

bool GroundReceiver::is_running() const {
    return udp_socket_ && udp_socket_->isOpen();
}

void GroundReceiver::on_udp_read_ready() {
    while (udp_socket_->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udp_socket_->pendingDatagramSize());
        
        QHostAddress sender;
        quint16 sender_port;
        
        udp_socket_->readDatagram(datagram.data(), datagram.size(), &sender, &sender_port);
        
        // 处理数据包
        process_packet((const uint8_t*)datagram.data(), datagram.size());
    }
}

void GroundReceiver::on_udp_error() {
    emit error(udp_socket_->errorString());
}

void GroundReceiver::on_cleanup_timeout() {
    cleanup_timeout_frames();
}

void GroundReceiver::process_packet(const uint8_t* data, size_t len) {
    // 检查最少包大小
    if (len < sizeof(PacketHeader)) {
        return;
    }
    
    // 解析包头
    const PacketHeader* header = (const PacketHeader*)data;
    
    // 验证魔数
    if (!isValidPacket(*header)) {
        return;
    }
    
    // 检查分片有效性
    if (header->chunk_index >= header->total_chunks) {
        return;
    }
    
    // 获取载荷
    uint16_t payload_size = header->data_len;
    if (sizeof(PacketHeader) + payload_size != len) {
        return;
    }
    
    const uint8_t* payload = data + sizeof(PacketHeader);
    
    // 更新统计
    {
        std::lock_guard<std::mutex> lock(stats_mutex_);
        stats_.total_packets++;
        stats_.total_bytes += len;
        stats_.bytes_this_second += len;
    }
    
    // 查找或创建帧缓冲区
    {
        std::lock_guard<std::mutex> lock(frame_buffers_mutex_);
        
        auto it = frame_buffers_.find(header->frame_id);
        if (it == frame_buffers_.end()) {
            // 创建新的帧缓冲区
            FrameBuffer fb;
            fb.frame_id = header->frame_id;
            fb.total_chunks = header->total_chunks;
            fb.timestamp = header->timestamp;
            fb.lat = header->lat;
            fb.lon = header->lon;
            fb.alt = header->alt;
            fb.receive_time_ms = QDateTime::currentMSecsSinceEpoch();
            
            it = frame_buffers_.insert({header->frame_id, fb}).first;
        }
        
        FrameBuffer& frame = it->second;
        
        // 添加分片（如果还没有的话）
        if (frame.chunks.find(header->chunk_index) == frame.chunks.end()) {
            std::vector<uint8_t> chunk(payload, payload + payload_size);
            frame.chunks[header->chunk_index] = chunk;
        }
        
        // 检查是否完整
        if (frame.is_complete()) {
            // 创建副本以在锁外处理
            FrameBuffer complete_frame = frame;
            frame_buffers_.erase(it);
            
            // 释放锁后处理
            handle_complete_frame(complete_frame);
        }
    }
}

void GroundReceiver::handle_complete_frame(const FrameBuffer& frame) {
    // 合并分片
    std::vector<uint8_t> jpeg_data = frame.merge();
    
    if (jpeg_data.empty()) {
        return;
    }
    
    // 解码 JPEG
    QImage image = decode_jpeg(jpeg_data);
    
    if (image.isNull()) {
        return;
    }
    
    // 更新统计
    {
        std::lock_guard<std::mutex> lock(stats_mutex_);
        stats_.total_frames++;
        stats_.frames_this_second++;
        last_complete_frame_id_ = frame.frame_id;
    }
    
    // 发出信号
    emit frameDecoded(image, frame.lat, frame.lon, frame.alt);
}

QImage GroundReceiver::decode_jpeg(const std::vector<uint8_t>& data) {
    if (data.empty()) {
        return QImage();
    }
    
    QImage image;
    image.loadFromData(data.data(), data.size(), "JPEG");
    return image;
}

void GroundReceiver::cleanup_timeout_frames() {
    uint64_t now_ms = QDateTime::currentMSecsSinceEpoch();
    
    std::lock_guard<std::mutex> lock(frame_buffers_mutex_);
    
    // 查找并删除超时的帧
    for (auto it = frame_buffers_.begin(); it != frame_buffers_.end();) {
        if (now_ms - it->second.receive_time_ms > FRAME_TIMEOUT_MS) {
            it = frame_buffers_.erase(it);
            stats_.dropped_frames++;
        } else {
            ++it;
        }
    }
    
    // 更新统计
    uint64_t current_time = QDateTime::currentMSecsSinceEpoch();
    if (current_time - stats_.last_stats_time >= 1000) {
        int fps = stats_.frames_this_second;
        int kbs = stats_.bytes_this_second / 1024;
        
        emit statsUpdated(fps, kbs);
        
        // 重置计数器
        stats_.frames_this_second = 0;
        stats_.bytes_this_second = 0;
        stats_.last_stats_time = current_time;
    }
}

void GroundReceiver::update_stats(uint32_t packet_size) {
    std::lock_guard<std::mutex> lock(stats_mutex_);
    stats_.total_bytes += packet_size;
    stats_.bytes_this_second += packet_size;
}
