#include <QAbstractSocket>
#include <QWebSocket>
#include <QJsonArray>

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

Server::Server(QObject* parent)
	: Service(parent)
{
}

Server::~Server()
{
}

void Server::processIncomeingJson(const QByteArray& jsonbytes)
{
	QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
	QJsonObject json = doc.object();
	QString type = json["MessageType"].toString();
	if(type == "ItemUpdate")
	{
		QJsonArray data = json["Data"].toArray();
		bool FullList = json["FullList"].toBool(false);
		std::vector<std::shared_ptr<Item>> items;
		std::vector<ItemFieldChanges> fieldChanges;
		for(QJsonValueRef itemjson : data)
		{
			QJsonObject jsonobject = itemjson.toObject();
			std::shared_ptr<Item> item = Item::loadItem(jsonobject);
			if(item)
			{
				qDebug()<<"Server got item"<<item->getName();
				item->setLoaded(FullList);
				fieldChanges.push_back(item->loadWithChanges(jsonobject));
				items.push_back(item);
			}
		}
		if(FullList && !items.empty())
		{
			requestReplaceItems(items);
			sigRequestSave();
		}
		else if(!items.empty())
		{
			std::vector<ItemUpdateRequest> updates;
			for(size_t i = 0; i < items.size(); i++)
			{
				ItemUpdateRequest request;
				request.payload = *items[i];
				request.changes = fieldChanges[i];
				request.type = ITEM_UPDATE_REMOTE;
				updates.push_back(request);
			}
			updateItems(updates);
		}
	}
	else
	{
		Service::processIncomeingJson(jsonbytes);
	}
}

void Server::handleSocketError()
{
	QObject* obj = sender();
	if (obj) {
		removeClient(static_cast<QTcpSocket*>(obj));
	}
}

void Server::handleSocketDisconnect()
{
	QObject* obj = sender();
	if (obj) {
		removeClient(static_cast<QTcpSocket*>(obj));
	}
}

void Server::removeClient(QTcpSocket* socket)
{
	for(size_t i = 0; i < clients.size(); i++)
	{
		if(clients[i].socket.tcpSocket == socket)
		{
			clients.erase(clients.begin() + i);
			--i;
		}
	}
}

void Server::removeClient(QWebSocket* socket)
{
	for(size_t i = 0; i < clients.size(); i++)
	{
		if(clients[i].socket.webSocket == socket)
		{
			clients.erase(clients.begin() + i);
			--i;
		}
	}
}

void Server::itemUpdated(ItemUpdateRequest update)
{
	QJsonArray items;
	QJsonObject itemjson;
	update.payload.storeWithChanges(itemjson, update.changes);
	items.append(itemjson);
	QJsonObject json = createMessage("ItemUpdate", items);
	json["FullList"] = false;
	sendJson(json);
}