#pragma once

#include "td/network/TCPSocket.h"
#include "td/protocol/PacketHandler.h"
#include "td/protocol/PacketDispatcher.h"
#include "td/game/Player.h"
#include "td/network/Connexion.h"

namespace td {
namespace server {

class Server;

struct KeepAlive {
	std::uint64_t keepAliveID = 0;
	std::uint64_t sendTime;
	bool recievedResponse = false;
};


class ServerConnexion : public protocol::Connexion {
private:
	Server* m_Server = nullptr;
	std::uint8_t m_ID;
	KeepAlive m_KeepAlive;
	game::Player* m_Player;
public:
	ServerConnexion();
	ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
	ServerConnexion(ServerConnexion&& move);
	virtual ~ServerConnexion();

	void SetServer(Server* server);

	virtual void HandlePacket(const protocol::PlayerLoginPacket* packet) override;
	virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
	virtual void HandlePacket(const protocol::SelectTeamPacket* packet) override;
	virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
	virtual void HandlePacket(const protocol::PlaceTowerPacket* packet) override;
	virtual void HandlePacket(const protocol::SendMobsPacket* packet) override;
	virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
	virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;

	std::uint8_t GetID() const { return m_ID; }
	const game::Player* GetPlayer() const { return m_Player; }
	game::Player* GetPlayer() { return m_Player; }

	virtual bool UpdateSocket();

	REMOVE_COPY(ServerConnexion);
private:
	void RegisterHandlers();
	void CheckKeepAlive();
	void SendKeepAlive();
	void InitConnection();
};

} // namespace server
} // namespace td
