#pragma once
#include "shared/api.pb.h"
#include "Common/CsdkErrorCode.h"
#include "Log/LogChatSdk.h"
#include "Log/CsdkLogMacros.h"

struct FMeta
{
	FString TraceId; // 链路追踪ID
	FString Version; // 服务端版本号
};

template <typename T>
struct TApiResult
{
	int32 Code = 0;
	FString Msg;
	FMeta Meta;
	T EmbedData;

	static TApiResult ParseAPIResult(const TArray<uint8>& Data)
	{
		heroim::client::v3beta::dto::shared::APIResult APIResult;
		APIResult.ParseFromArray(Data.GetData(),Data.Num());
	
		T EmbedData;
		EmbedData.ParseFromArray(APIResult.data().c_str(),APIResult.data().length()) ;
		TApiResult Result;
		Result.Code =APIResult.code();
		Result.Msg =UTF8_TO_TCHAR(APIResult.msg().c_str());
		Result.Meta.Version = UTF8_TO_TCHAR(APIResult.meta().version().c_str());
		Result.Meta.TraceId =  UTF8_TO_TCHAR(APIResult.meta().traceid().c_str());
		Result.EmbedData = EmbedData;
		FString ClassType;
#if PLATFORM_WINDOWS
		ClassType = UTF8_TO_TCHAR(typeid(T).name());
#else
		ClassType = UTF8_TO_TCHAR(TApiResult<T>::Get());
#endif
		if(Result.Code == ECsdkErrorCode::Success)
		{
			CSDK_LOG(LogChatSdk,Log,TEXT("ClassType: %s, DebugMsg: %s"),*ClassType,*Result.FormatDebugMsg());
		}
		else
		{
			CSDK_LOG(LogChatSdk,Error,TEXT("ClassType: %s, DebugMsg: %s"),*ClassType,*Result.FormatDebugMsg());
		}
		
		return Result;
	}

	static T ParseT(const TArray<uint8>& Data)
	{
		T Result;
		Result.ParseFromArray(Data.GetData(),Data.Num()) ;
		FString ClassType;
#if PLATFORM_WINDOWS
			ClassType = UTF8_TO_TCHAR(typeid(T).name());
#else
			ClassType = UTF8_TO_TCHAR(TApiResult<T>::Get());
#endif
		CSDK_LOG(LogChatSdk,Log,TEXT("ClassType: %s, Content: %s"),*ClassType,*FCsdkCommonTools::ParsePbToJson(Result));
		return Result;
	}

	FString FormatDebugMsg() const
	{
		return FString::Printf(TEXT("Code:%d, Msg: %s, TraceId:%s, Version: %s,Content:%s"),Code,*Msg, *Meta.TraceId, *Meta.Version,
			 *FCsdkCommonTools::ParsePbToJson(EmbedData));
	}
#if !PLATFORM_WINDOWS
	static const char* Get() {
		static const char* name = GetTypeName();
		return name;
	}

private:
	static const char* GetTypeName() {
#ifdef _MSC_VER
		return __FUNCSIG__;
#else
		return __PRETTY_FUNCTION__;
#endif
	}
#endif
};

