#pragma once

#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "Networking.h"
#include "Serialization/JsonSerializer.h"
#include "UDPInstanceSubsystem.generated.h"

USTRUCT(BlueprintType)
struct FDeviceData
{
    GENERATED_BODY()

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    FString ID;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float X;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float Y;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float Z;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float Yaw;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float Roll;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float Pitch;

    // JSON 序列化
    TSharedPtr<FJsonObject> ToJsonObject() const;
    static bool FromJsonObject(const TSharedPtr<FJsonObject>& JsonObject, FDeviceData& OutDeviceData);
};

USTRUCT(BlueprintType)
struct FDeviceDataMap
{
    GENERATED_BODY()
    
    UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Device Data")
    TMap<FString, FDeviceData> ReceivedDataMap;
};

// 声明代理类型
// C++
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDeviceDataReceived, const FDeviceDataMap&, ReceivedDataMap);

UCLASS()
class TERRACOTTAWARRIORS_API UUDPInstanceSubsystem : public UGameInstanceSubsystem
{
    GENERATED_BODY()

public:
    virtual void Initialize(FSubsystemCollectionBase& Collection) override;
    virtual void Deinitialize() override;

    // 设置要跟踪的Pawn
    UFUNCTION(BlueprintCallable, Category = "UDP")
    void SetTrackedPawn(APawn* NewPawn);

    // 发送设备数据
    UFUNCTION(BlueprintCallable, Category = "UDP")
    void SendDeviceData(const FDeviceData& DeviceData);

    // 发送当前Pawn的位置数据
    UFUNCTION(BlueprintCallable, Category = "UDP")
    void SendCurrentPawnData();

    // 设备数据接收代理
    UPROPERTY(BlueprintAssignable, Category = "UDP")
    FOnDeviceDataReceived OnDeviceDataReceived;


    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    FString UUID;

    // UDPInstanceSubsystem.h 中合适的位置（如类前向声明或public部分）
    DECLARE_DYNAMIC_DELEGATE_TwoParams(FOnActorSpawned, AActor*, SpawnedActor, const FString&, ID);

    UFUNCTION(BlueprintCallable)
    void SpawnActorInGameThread(TSubclassOf<AActor> Actor, const FVector& Location, const FRotator& Rotation, const FString& ID, FOnActorSpawned OnActorSpawned);

private:
    // UDP 发送相关
    FSocket* SenderSocket;
    FIPv4Endpoint RemoteEndpoint;

    

    // UDP 接收相关
    FSocket* ReceiverSocket;
    FUdpSocketReceiver* SocketReceiver;
    TArray<FDeviceData> ReceivedDeviceData;
    FCriticalSection ReceivedDataCriticalSection;

    // 要跟踪的Pawn
    UPROPERTY(Transient)
    APawn* TrackedPawn;

    // 初始化网络
    void InitNetwork();

    // 清理网络
    void CleanupNetwork();

    // UDP 接收回调
    void OnDataReceived(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt);

    // 解析接收到的数据
    void ParseReceivedData(const FString& DataString);
};