// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include <CoreMinimal.h>
#include <memory>
#include "LovenseTypes.h"

// EXTERNAL INCLUDES
#include <Runtime/Launch/Resources/Version.h>
#if ENGINE_MAJOR_VERSION > 5 || ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2
#include <Engine/TimerHandle.h>
#else
#include <Engine/EngineTypes.h>
#endif

// INTERNAL INCLUDES


class LovenseToyEventsWebSocketHandler : public TSharedFromThis<LovenseToyEventsWebSocketHandler> {
public:
	TSharedPtr<class IWebSocket> webSocket;
	FOnEventCode codeResponse;
	FOnGetLovenseEventToys getToysCallback;
	FOnLovenseConnectStatusEvent connectCallBack;
	FOnLovenseBatteryEvent batteryCallBack;
	FOnFunctionsEvent valueCallBack;
	FOnEveryShakeEvent everyShakeCallBack;
	FOnButtonEvent buttonCallBack;
	FOnMotionChangedEvent motionChangedCallback;


	LovenseToyEventsWebSocketHandler();
	/*TSharedPtr <LovenseToyEventsWebSocketHandler> SharedThis()
	{
		return TSharedPtr<LovenseToyEventsWebSocketHandler>(this->shared_from_this());
	}
	TSharedPtr<const LovenseToyEventsWebSocketHandler> SharedThisConst() const
	{
		return TSharedPtr<const LovenseToyEventsWebSocketHandler>(this->shared_from_this());
	}*/
	bool Initialize(const FString& ip, int32 port, FOnEventCode& resultCodeCallback, FOnGetLovenseEventToys& toysCallback);
	void Shutdown();
	bool SendJsonData(const FString& data);
	void SetConnectEventCallback( FOnLovenseConnectStatusEvent connectCallback);
	void SetBatteryEventCallback(FOnLovenseBatteryEvent batteryCallback);
	void SetFunctionsValueEventCallback(FOnFunctionsEvent functionsValueCallback);
	void SetEveryShakeEventCallback( FOnEveryShakeEvent everyShakeCallback);
	void SetButtonEventCallback(FOnButtonEvent buttonCallback);
	void SetMotionChangedEventCallback(FOnMotionChangedEvent motionChangedCallback);
//private:
	void OnConnected();
	void OnConnectionError(const FString& error);
	void OnConnectionClosed(int32 statusCode, const FString& reason, bool bWasClean);
	void OnMessage(const FString& message);
	void OnRawMessage(const void* data, SIZE_T size, SIZE_T bytesRemaining);
	void OnMessageSent(const FString& messageString);
	void Ping();
	TSharedPtr<class IWebSocket> GetSocket();

private:
	FTimerHandle pingTimerHandle;
	double pingTimestamp;
	FString socketIp;
	int32 socketPort;
};
