#ifdef NETWORK
#ifdef EMSCRIPTEN
#include "WebSocketClientEmscripten.h"
#include <iostream>
#include <SDL2/SDL.h>

namespace ZL {
    void WebSocketClientEmscripten::Connect(const std::string& host, uint16_t port) {
        // Формируем URL. Обратите внимание, что в Web часто лучше использовать ws://localhost
        //std::string url = "ws://" + host + ":" + std::to_string(port);
        std::string url = "wss://api.spacegame.fishrungames.com";
        //std::string url = "ws://localhost:8081";
        EmscriptenWebSocketCreateAttributes attr = {
            url.c_str(),
            nullptr,
            EM_TRUE // create_on_main_thread
        };

        socket_ = emscripten_websocket_new(&attr);

        emscripten_websocket_set_onopen_callback(socket_, this, onOpen);
        emscripten_websocket_set_onmessage_callback(socket_, this, onMessage);
        emscripten_websocket_set_onerror_callback(socket_, this, onError);
        emscripten_websocket_set_onclose_callback(socket_, this, onClose);

        connected = false;
    }

    void WebSocketClientEmscripten::Disconnect() {
        if (socket_ > 0) {
            emscripten_websocket_close(socket_, 1000, "User disconnected");
            emscripten_websocket_delete(socket_);
            socket_ = 0;
        }
        connected = false;
    }

    void WebSocketClientEmscripten::flushOutgoingQueue() {
        std::lock_guard<std::mutex> lock(outgoingMutex);
        if (!socket_) return;
        while (!outgoingQueue.empty()) {
            const std::string &m = outgoingQueue.front();
            emscripten_websocket_send_utf8_text(socket_, m.c_str());
            outgoingQueue.pop();
        }
    }

    void WebSocketClientEmscripten::Send(const std::string& message) {
        std::string signedMsg = SignMessage(message);

        {
            std::lock_guard<std::mutex> lock(outgoingMutex);
            if (connected && socket_ > 0) {
                std::cout << "[WebWS] Sending message (immediate): " << signedMsg << std::endl;
                emscripten_websocket_send_utf8_text(socket_, signedMsg.c_str());
                return;
            }
            outgoingQueue.push(signedMsg);
            std::cout << "[WebWS] Queued outgoing message (waiting for open): " << signedMsg << std::endl;
        }
    }

    void WebSocketClientEmscripten::Poll() {
        // Локальная очередь для минимизации времени блокировки мьютекса
        std::queue<std::string> localQueue;

        if (messageQueue.empty()) return;
        std::swap(localQueue, messageQueue);

        while (!localQueue.empty()) {
            const std::string& msg = localQueue.front();
            std::cout << "[WebWS] Processing message: " << msg << std::endl;

            // Передаем в базовый класс для парсинга игровых событий (BOXES, UPD, и т.д.)
            HandlePollMessage(msg);

            localQueue.pop();
        }
    }

    // --- Колбэки ---

    EM_BOOL WebSocketClientEmscripten::onOpen(int eventType, const EmscriptenWebSocketOpenEvent* e, void* userData) {
        auto* self = static_cast<WebSocketClientEmscripten*>(userData);
        self->connected = true;
        std::cout << "[WebWS] Connection opened" << std::endl;

        self->flushOutgoingQueue();

        return EM_TRUE;
    }

    EM_BOOL WebSocketClientEmscripten::onMessage(int eventType, const EmscriptenWebSocketMessageEvent* e, void* userData) {
        std::cout << "[WebWS] onMessage " << std::endl;
        auto* self = static_cast<WebSocketClientEmscripten*>(userData);
        if (e->isText && e->data) {
            std::string msg(reinterpret_cast<const char*>(e->data), e->numBytes);
            self->messageQueue.push(msg);
        }
        return EM_TRUE;
    }

    EM_BOOL WebSocketClientEmscripten::onError(int eventType, const EmscriptenWebSocketErrorEvent* e, void* userData) {
        auto* self = static_cast<WebSocketClientEmscripten*>(userData);
        self->connected = false;
        std::cerr << "[WebWS] Error detected" << std::endl;
        return EM_TRUE;
    }

    EM_BOOL WebSocketClientEmscripten::onClose(int eventType, const EmscriptenWebSocketCloseEvent* e, void* userData) {
        auto* self = static_cast<WebSocketClientEmscripten*>(userData);
        self->connected = false;
        std::cout << "[WebWS] Connection closed" << std::endl;
        return EM_TRUE;
    }

}

#endif
#endif

