#pragma once

#include "network/TCPSocket.h"
#include "protocol/PacketHandler.h"
#include "protocol/PacketDispatcher.h"
#include "game/Player.h"
#include "game/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);
    virtual void HandlePacket(const protocol::KeepAlivePacket* packet);
    virtual void HandlePacket(const protocol::SelectTeamPacket* packet);
    virtual void HandlePacket(const protocol::DisconnectPacket* packet);
    virtual void HandlePacket(const protocol::PlaceTowerPacket* packet);
    virtual void HandlePacket(const protocol::SendMobsPacket* packet);
    virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
    virtual void HandlePacket(const protocol::RemoveTowerPacket* packet);

    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
