// IndiEleven SDK v1.0 for Unreal Engine 5
// https://indieleven.com
#pragma once

#include "CoreMinimal.h"
#include "Http.h"
#include "Dom/JsonObject.h"
#include "Serialization/JsonSerializer.h"
#include "IndiEleven.generated.h"

DECLARE_DYNAMIC_DELEGATE_OneParam(FOnIEResult, const FString&, ResponseJson);

UCLASS(Blueprintable, BlueprintType)
class YOURGAME_API UIndiEleven : public UObject
{
    GENERATED_BODY()

public:
    UPROPERTY() FString ApiKey;
    UPROPERTY() FString PlayerToken;
    UPROPERTY() FString PlayerJson;

    static const FString BASE_URL;

    UFUNCTION(BlueprintCallable, Category="IndiEleven")
    static UIndiEleven* Create(const FString& InApiKey);

    // ─── PLAYER ACCOUNTS ─────────────────────────────
    UFUNCTION(BlueprintCallable, Category="IndiEleven|Player")
    void Register(const FString& Username, const FString& Email, const FString& Password, const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Player")
    void Login(const FString& Email, const FString& Password, const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Player")
    void Logout(const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Player")
    void GetProfile(const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Player")
    bool IsLoggedIn() const { return !PlayerToken.IsEmpty(); }

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Player")
    FString GetPlayer() const { return PlayerJson; }

    // ─── LEADERBOARDS ────────────────────────────────
    UFUNCTION(BlueprintCallable, Category="IndiEleven|Leaderboard")
    void SubmitScore(const FString& LeaderboardId, const FString& PlayerId, int32 Score, const FString& Username, const FString& Metadata, const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Leaderboard")
    void GetScores(const FString& LeaderboardId, const FString& PlayerId, const FOnIEResult& Callback);

    // ─── CLOUD SAVE ──────────────────────────────────
    UFUNCTION(BlueprintCallable, Category="IndiEleven|CloudSave")
    void Save(const FString& DataJson, const FString& SaveKey, const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|CloudSave")
    void LoadSave(const FString& SaveKey, const FOnIEResult& Callback);

    // ─── ACHIEVEMENTS ────────────────────────────────
    UFUNCTION(BlueprintCallable, Category="IndiEleven|Achievements")
    void GetAchievements(const FString& PlayerId, const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Achievements")
    void UnlockAchievement(const FString& PlayerId, const FString& AchievementId, const FOnIEResult& Callback);

    UFUNCTION(BlueprintCallable, Category="IndiEleven|Achievements")
    void GetPlayerAchievements(const FString& PlayerId, const FOnIEResult& Callback);

private:
    void MakeRequest(const FString& Endpoint, const FString& Verb, const FString& Body, const FOnIEResult& Callback);
    void SaveSession(const FString& Token, const FString& Json);
    void ClearSession();
};
