#include "client2.h"
#include "PQSMsg.h"
#include "dealMsg.h"
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <memory>
#include <mutex>
#include <unordered_map>

// 配置参数
constexpr int BASE_RECONNECT_DELAY = 5000;    // 基础重连延迟(ms)
constexpr int MAX_RECONNECT_DELAY = 60000;    // 最大重连延迟(ms)
constexpr const char* SERVER_IP = "101.132.39.45"; // 目标服务器IP"101.132.39.45"
constexpr int SERVER_PORT = 1056;             // 目标服务器端口1056

static uv_loop_t* global_loop = nullptr;
static uv_timer_t monitor_timer;
extern SafeMessageQueue message_queue;

// ClientContext 实现
ClientContext::ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index)
    : loop(loop), state(ConnectionState::DISCONNECTED),
    reconnect_attempts(0), shutdown(false), device_info(device), index_(index) {

    recv_buffer_.reserve(4096); // 预分配4KB缓冲区

    // 初始化 TCP 句柄
    uv_tcp_init(loop, &client);
    client.data = this;

    // 初始化定时器
    uv_timer_init(loop, &timer);
    timer.data = this;

    // 初始化重连定时器
    uv_timer_init(loop, &reconnect_timer);
    reconnect_timer.data = this;
}

ClientContext::~ClientContext() {
    stop_timers();
    close_handles();
}

void ClientContext::init_tcp() {
    if (!uv_is_active((uv_handle_t*)&client)) {
        uv_tcp_init(loop, &client);
        client.data = this;
    }
}

void ClientContext::start_timer() {
    if (!uv_is_active((uv_handle_t*)&timer)) {
        uv_timer_start(&timer, on_timer, 6000, 6000);
    }
}

void ClientContext::start_reconnect_timer(int delay) {
    if (!uv_is_active((uv_handle_t*)&reconnect_timer)) {
        uv_timer_start(&reconnect_timer, try_reconnect, delay, 0);
    }
}

void ClientContext::stop_timers() {
    if (uv_is_active((uv_handle_t*)&timer)) uv_timer_stop(&timer);
    if (uv_is_active((uv_handle_t*)&reconnect_timer)) uv_timer_stop(&reconnect_timer);
}

void ClientContext::close_handles() {
    if (!uv_is_closing((uv_handle_t*)&client)) {
        uv_close((uv_handle_t*)&client, nullptr);
    }
    if (!uv_is_closing((uv_handle_t*)&timer)) {
        uv_close((uv_handle_t*)&timer, nullptr);
    }
    if (!uv_is_closing((uv_handle_t*)&reconnect_timer)) {
        uv_close((uv_handle_t*)&reconnect_timer, nullptr);
    }
}

// 添加接收数据到缓冲区并处理
void ClientContext::append_and_process_data(const char* data, size_t len) {
    std::lock_guard<std::mutex> lock(buffer_mutex_);

    // 添加到缓冲区
    recv_buffer_.insert(recv_buffer_.end(), data, data + len);

    // 处理缓冲区数据
    process_buffer();

    // 检查缓冲区大小防止内存溢出
    if (recv_buffer_.size() > 10 * 1024 * 1024) { // 10MB限制
        recv_buffer_.clear();
        std::cerr << "[Device " << device_info.device_id
            << "] Buffer overflow, cleared\n";
    }
}

// 注意：这个函数必须在 buffer_mutex_ 已被锁定的情况下调用
void ClientContext::process_buffer() {
    constexpr int MSG_HEAD_LEN = 6; // 最小包头长度

    while (true) {
        // 检查缓冲区大小是否足够解析包头
        if (recv_buffer_.size() < MSG_HEAD_LEN)
            break;

        // 云服务器状态报文检查 (EB 90 EB 90)
        if (recv_buffer_.size() >= 4 &&
            recv_buffer_[0] == 0xEB && recv_buffer_[1] == 0x90 &&
            recv_buffer_[2] == 0xEB && recv_buffer_[3] == 0x90) {

            const int packageLen = 150; // 固定长度
            if (recv_buffer_.size() < packageLen)
                break;

            // 提取完整报文
            std::vector<unsigned char> packet(
                recv_buffer_.begin(),
                recv_buffer_.begin() + packageLen
            );

            // 从缓冲区移除已处理数据
            recv_buffer_.erase(
                recv_buffer_.begin(),
                recv_buffer_.begin() + packageLen
            );

            // 放入消息队列
            put_packet_into_queue(packet);
            continue;
        }

        // 标准报文检查 (EB 90)
        if (recv_buffer_[0] != 0xEB || recv_buffer_[1] != 0x90) {
            // 非法包头，清空缓冲区
            recv_buffer_.clear();
            break;
        }

        // 解析包长度 (小端序)
        if (recv_buffer_.size() < 6)
            break;

        uint16_t body_len = (recv_buffer_[4] << 8) | recv_buffer_[5];
        const int packageLen = body_len + 10; // 基础长度+扩展

        if (recv_buffer_.size() < packageLen)
            break;

        // 提取完整报文
        std::vector<unsigned char> packet(
            recv_buffer_.begin(),
            recv_buffer_.begin() + packageLen
        );

        // 从缓冲区移除已处理数据
        recv_buffer_.erase(
            recv_buffer_.begin(),
            recv_buffer_.begin() + packageLen
        );

        // 放入消息队列
        put_packet_into_queue(packet);
    }
}

void ClientContext::put_packet_into_queue(
    const std::vector<unsigned char>& packet)
{
    deal_message_t msg;
    msg.device_id = device_info.device_id;
    msg.mac = device_info.mac;
    msg.points = device_info.points;

    msg.length = packet.size();
    msg.data = static_cast<char*>(malloc(msg.length));
    memcpy(msg.data, packet.data(), msg.length);

    if (!message_queue.push(msg)) {
        free(msg.data);
        std::cerr << "[Device " << device_info.device_id
            << "] Queue full, dropping packet\n";
    }
}

/* 缓冲区分配回调 */
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
    buf->base = new char[suggested_size];
    buf->len = suggested_size;
}

/* 数据读取回调 */
void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
    ClientContext* ctx = static_cast<ClientContext*>(stream->data);

    if (nread < 0) {
        if (nread != UV_EOF) {
            std::cerr << "[Device " << ctx->device_info.device_id
                << "] RECV ERROR: " << uv_strerror(nread) << std::endl;
        }
        uv_close((uv_handle_t*)stream, on_close);
        delete[] buf->base;
        return;
    }

    if (nread > 0) {
        // 使用公共方法添加并处理数据
        ctx->append_and_process_data(buf->base, nread);
        std::cout << "on_read: " << ctx->device_info.mac << " get " << nread << " bytes" << std::endl;
    }

    delete[] buf->base;
}

/* 数据写入回调 */
void on_write(uv_write_t* req, int status) {
    ClientContext* ctx = static_cast<ClientContext*>(req->handle->data);

    if (status < 0) {
        std::cerr << "[Device " << ctx->device_info.device_id
            << "] SEND ERROR: " << uv_strerror(status) << std::endl;
    }
    std::cout << "on_write: " << ctx->device_info.mac << " down!" << std::endl;
    delete[] static_cast<char*>(req->data);  // 释放发送数据缓冲区
    delete req;        // 释放写入请求
}

/* 定时发送回调 */
void on_timer(uv_timer_t* handle) {
    ClientContext* ctx = static_cast<ClientContext*>(handle->data);

    if (ctx->state != ConnectionState::CONNECTED) {
        return;
    }
    std::cout << "on_timer: " << ctx->device_info.mac << " send!"<< std::endl;
    // 使用装置自己的MAC地址生成登录报文
    auto binary_data = generate_frontlogin_message(ctx->device_info.mac);

    // 调用发送函数
    send_binary_data(ctx, binary_data.data(), binary_data.size());

    //ClientManager::instance().send_to_device(ctx->device_info.mac, binary_data.data(), binary_data.size());

    // 根据装置状态发送其他数据
    if (ctx->device_info.status == 1) { // 在线状态
        // 可以发送装置配置信息或测点数据
    }
}

/* 发送二进制报文函数 */
void send_binary_data(ClientContext* ctx, const unsigned char* data, size_t data_size) {
    if (ctx->state != ConnectionState::CONNECTED) {
        std::cerr << "[Device " << ctx->device_info.device_id
            << "] Cannot send: not connected" << std::endl;
        return;
    }

    uv_buf_t buf = uv_buf_init(const_cast<char*>(reinterpret_cast<const char*>(data)), data_size);
    uv_write_t* write_req = new uv_write_t;

    // 复制数据以确保安全
    char* data_copy = new char[data_size];
    memcpy(data_copy, data, data_size);
    write_req->data = data_copy;

    int ret = uv_write(write_req, (uv_stream_t*)&ctx->client, &buf, 1, on_write);
    if (ret < 0) {
        std::cerr << "[Device " << ctx->device_info.device_id
            << "] uv_write failed: " << uv_strerror(ret) << std::endl;
        delete[] data_copy;
        delete write_req;
    }
}

/* 连接关闭回调 */
void on_close(uv_handle_t* handle) {
    ClientContext* ctx = static_cast<ClientContext*>(handle->data);
    ctx->state = ConnectionState::DISCONNECTED;
    std::cerr << "[Device " << ctx->device_info.device_id << "] Connection closed" << std::endl;

    ctx->stop_timers();

    if (!ctx->shutdown) {
        int delay = BASE_RECONNECT_DELAY * pow(2, ctx->reconnect_attempts);
        delay = delay > MAX_RECONNECT_DELAY ? MAX_RECONNECT_DELAY : delay;

        std::cout << "[Device " << ctx->device_info.device_id
            << "] Reconnecting in " << delay << "ms (attempt "
            << ctx->reconnect_attempts + 1 << ")" << std::endl;

        ctx->reconnect_attempts++;
        ctx->start_reconnect_timer(delay);
    }
}

/* 尝试重连 */
void try_reconnect(uv_timer_t* timer) {
    ClientContext* ctx = static_cast<ClientContext*>(timer->data);

    if (ctx->state != ConnectionState::DISCONNECTED || ctx->shutdown) {
        return;
    }

    std::cerr << "[Device " << ctx->device_info.device_id << "] Attempting reconnect" << std::endl;

    ctx->init_tcp();
    ctx->state = ConnectionState::CONNECTING;

    struct sockaddr_in addr;
    uv_ip4_addr(SERVER_IP, SERVER_PORT, &addr);

    uv_connect_t* req = new uv_connect_t;
    req->data = ctx;

    int ret = uv_tcp_connect(req, &ctx->client, (const struct sockaddr*)&addr, on_connect);
    if (ret < 0) {
        std::cerr << "[Device " << ctx->device_info.device_id
            << "] Connect error: " << uv_strerror(ret) << std::endl;
        delete req;
        uv_close((uv_handle_t*)&ctx->client, on_close);
    }
}

/* 连接建立回调 */
void on_connect(uv_connect_t* req, int status) {
    ClientContext* ctx = static_cast<ClientContext*>(req->data);
    delete req;

    if (status < 0) {
        std::cerr << "[Device " << ctx->device_info.device_id
            << "] Connect failed: " << uv_strerror(status) << std::endl;
        if (!uv_is_closing((uv_handle_t*)&ctx->client)) {
            uv_close((uv_handle_t*)&ctx->client, on_close);
        }
        return;
    }

    std::cerr << "[Device " << ctx->device_info.device_id << "] Connected to server" << std::endl;

    ctx->state = ConnectionState::CONNECTED;
    ctx->reconnect_attempts = 0;

    uv_read_start((uv_stream_t*)&ctx->client, alloc_buffer, on_read);
    ctx->start_timer();
}

/* 初始化所有客户端连接 */
void init_clients(uv_loop_t* loop, const std::vector<DeviceInfo>& devices) {
    auto& manager = ClientManager::instance();
    manager.set_loop(loop);  // 使用公共方法设置事件循环

    for (const auto& device : devices) {
        manager.add_device(device);
    }
}

/* 停止所有客户端 */
void stop_all_clients() {
    auto& manager = ClientManager::instance();
    manager.stop_all();
}

/* 连接监控回调 */
void monitor_connections(uv_timer_t* handle) {
    static int recovery_counter = 0;
    if (++recovery_counter >= 5) {
        int active_count = 0;
        auto& manager = ClientManager::instance();
        size_t total_clients = manager.client_count();

        // 实际应用中，这里需要实现获取活动连接数的方法
        // 简化处理，只显示总连接数
        std::cout << "Total connections: " << total_clients << std::endl;
        recovery_counter = 0;
    }
}

static void close_walk_cb(uv_handle_t* handle, void* arg) {
    if (!uv_is_closing(handle)) {
        uv_close(handle, nullptr);
    }
}

/* 启动客户端连接 */
void start_client_connect(const std::vector<DeviceInfo>& devices) {
    // 创建全局事件循环
    global_loop = uv_default_loop();

    // 初始化所有客户端
    init_clients(global_loop, devices);

    // 启动连接监控
    uv_timer_init(global_loop, &monitor_timer);
    uv_timer_start(&monitor_timer, monitor_connections, 1000, 1000);

    // 运行事件循环
    uv_run(global_loop, UV_RUN_DEFAULT);

    // 添加资源清理阶段
    while (uv_loop_alive(global_loop)) {
        uv_run(global_loop, UV_RUN_ONCE);
    }

    // 安全关闭事件循环
    int err = uv_loop_close(global_loop);
    if (err) {
        std::cerr << "uv_loop_close error: " << uv_strerror(err) << std::endl;
        // 强制清理残留句柄（调试用）
        uv_walk(global_loop, close_walk_cb, nullptr);
        uv_run(global_loop, UV_RUN_NOWAIT);
    }

    // 清理所有客户端
    stop_all_clients();
    global_loop = nullptr;
}

// ClientManager 成员函数实现
void ClientManager::add_device(const DeviceInfo& device) {
    std::lock_guard<std::mutex> lock(mutex_);

    if (!loop_) {
        std::cerr << "[Device " << device.device_id << "] Cannot add: event loop not set\n";
        return;
    }

    // 检查是否已存在相同ID的装置
    if (clients_.find(device.device_id) != clients_.end()) {
        std::cerr << "[Device " << device.device_id << "] Already exists, skip adding\n";
        return;
    }

    // 创建新的客户端上下文
    int index = clients_.size();
    auto ctx = std::unique_ptr<ClientContext>(new ClientContext(loop_, device, index));

    // 添加到管理映射
    clients_[device.device_id] = std::move(ctx);

    // 启动连接
    try_reconnect(&clients_[device.device_id]->reconnect_timer);
    std::cout << "[Device " << device.device_id << "] Added successfully\n";
}

void ClientManager::remove_device(const std::string& device_id) {
    std::lock_guard<std::mutex> lock(mutex_);

    auto it = clients_.find(device_id);
    if (it == clients_.end()) {
        std::cerr << "[Device " << device_id << "] Not found, cannot remove\n";
        return;
    }

    // 关闭连接并移除
    it->second->shutdown = true;
    it->second->close_handles();
    clients_.erase(it);
    std::cout << "[Device " << device_id << "] Removed successfully\n";
}

bool ClientManager::send_to_device(const std::string& identifier,
    const unsigned char* data,
    size_t size) {
    std::lock_guard<std::mutex> lock(mutex_);

    for (auto& pair : clients_) {
        auto& ctx = pair.second;
        // 匹配装置ID或MAC地址
        if (ctx->device_info.device_id == identifier ||
            ctx->device_info.mac == identifier) {

            if (ctx->state == ConnectionState::CONNECTED) {
                send_binary_data(ctx.get(), data, size);
                return true;
            }
            std::cerr << "[Device " << identifier << "] Not connected\n";
            return false;
        }
    }

    std::cerr << "[Device " << identifier << "] Not found\n";
    return false;
}

void ClientManager::stop_all() {
    std::lock_guard<std::mutex> lock(mutex_);
    for (auto& pair : clients_) {
        pair.second->shutdown = true;
        pair.second->close_handles();
    }
    clients_.clear();
}