#include <QWebSocketServer>
#include <vector>
#include <QWebSocket>
#include <QJsonArray>

#include "items/item.h"
#include "server.h"
#include "websocketserver.h"

WebSocketServer::WebSocketServer(const QString &serverName, QObject* parent)
	: Server(parent),
	  server(serverName, QWebSocketServer::NonSecureMode, this)
{
	connect(&server, &QWebSocketServer::newConnection, this, &WebSocketServer::incomingConnection);
}

WebSocketServer::~WebSocketServer()
{
	// Clean up WebSocket clients (they need special handling)
	for(auto& client : clients)
	{
		if(client.socket.webSocket)
		{
			client.socket.webSocket->close();
			delete client.socket.webSocket;
		}
	}
}

void WebSocketServer::sendJson(const QJsonObject& json)
{
	QByteArray jsonData = QJsonDocument(json).toJson();
	for(auto& client : clients)
	{
		if(client.socket.webSocket && client.socket.webSocket->state() == QAbstractSocket::ConnectedState)
		{
			client.socket.webSocket->sendTextMessage(QString::fromUtf8(jsonData));
		}
	}
}

void WebSocketServer::processIncomeingJson(const QByteArray& jsonbytes)
{
	// Validate JSON first (WebSockets may receive malformed data)
	QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
	if(!doc.isObject())
	{
		qWarning() << "Invalid JSON received:" << QString::fromUtf8(jsonbytes);
		return;
	}

	Server::processIncomeingJson(jsonbytes);
}

bool WebSocketServer::launch(const QHostAddress &address, quint16 port)
{
	qInfo()<<"WebSocket server launched on"<<address<<"port"<<port;
	return server.listen(address, port);
}

void WebSocketServer::incomingConnection()
{
	while(server.hasPendingConnections())
	{
		QWebSocket* client = server.nextPendingConnection();
		qDebug() << "Got new WebSocket client from" << client->peerAddress().toString();
		if(client)
		{
			Client c;
			c.socket.webSocket = client;
			clients.push_back(c);
			connect(client, &QWebSocket::errorOccurred, this, [this, client]() { removeClient(client); });
			connect(client, &QWebSocket::disconnected, this, [this, client]() { removeClient(client); });
			connect(client, &QWebSocket::textMessageReceived, this, &WebSocketServer::textMessageReceived);
		}
	}
}

void WebSocketServer::textMessageReceived(const QString &message)
{
	QByteArray jsonData = message.toUtf8();
	processIncomeingJson(jsonData);
}
