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

#pragma once

#include "CoreMinimal.h"
#include "Data/CsdkMicState.h"
#include "UObject/Object.h"
#include "Data/CsdkSpeakerState.h"
#include "CsdkVoiceBase.generated.h"


DECLARE_DYNAMIC_DELEGATE_FourParams(FRecordFileCompleted, int32, Result,const FString&, FilePath, float, Duration, int32, FileSize );
DECLARE_DYNAMIC_DELEGATE_ThreeParams(FUploadRecordedFileCompleted, int32, Result, const FString&, FilePath, const FString&, FileId);
DECLARE_DYNAMIC_DELEGATE_ThreeParams(FDownloadRecordedFileCompleted, int32, Result, const FString&, FilePath, const FString&, FileId);
DECLARE_DYNAMIC_DELEGATE_OneParam(FPlayRecordedFileCompleted, int32, Result);
DECLARE_DYNAMIC_DELEGATE_ThreeParams(FSpeechToTextCompleted, int32, Result,const FString&, FileId,const FString&, Text);
DECLARE_DYNAMIC_DELEGATE_ThreeParams(FStreamSpeechToTextRunning, int32, Index, int32, SliceType,const FString&, Text);
DECLARE_DYNAMIC_DELEGATE_FourParams(FStreamSpeechToTextCompleted, int32, Result,const FString&, FilePath,const FString&, FileId,const FString&, Text);

DECLARE_DYNAMIC_DELEGATE_TwoParams(FEnterRoomCompleted, int32, Result,const FString&, RoomId);
DECLARE_DYNAMIC_DELEGATE_TwoParams(FExitRoomCompleted, int32, Result,const FString&, RoomId);
DECLARE_DYNAMIC_DELEGATE_TwoParams(FSwitchRoomCompleted, int32, Result,const FString&, RoomId);

class UCsdkVoiceSupportSubsystem;

enum class EVoiceRoomStatus
{
	NoRoom,
	PreEnterRoom,
	Online,
	Offline,
	PreExitRoom,
};

UCLASS(Abstract)
class CSDKRUNTIME_API UCsdkVoiceBase : public UObject
{
	GENERATED_BODY()

public:
	UPROPERTY(BlueprintReadWrite, Category= "CsdkVoice", meta=(ExposeOnSpawn = true))
	FString AppID;
	UPROPERTY(BlueprintReadWrite, Category= "CsdkVoice", meta=(ExposeOnSpawn = true))
	FString AppKey;
	UPROPERTY(BlueprintReadWrite, Category= "CsdkVoice", meta=(ExposeOnSpawn = true))
	FString OpenId;
	
	//初始化&&反初始化
	virtual bool Init( UCsdkVoiceSupportSubsystem* CsdkVoiceSupportSubsystem);;
	virtual int32 UnInit();

	//暂停语音功能&&恢复语音功能
	virtual int32 Pause() { return  -1; }
	virtual int32 Resume() { return  -1; }

	//开始录音&&停止录音
	virtual int32 StartRecording(const FRecordFileCompleted& InRecordFileCompleted) { return -1; }
	virtual int32 StopRecordingRaw() { return -1;}
	virtual int32 StopRecording() { return -1;}
	virtual int32 CancelRecording() {return -1;}

	//语音文件上传&&下载
	virtual int32 UploadRecordedFile(const FString& FilePath, const FUploadRecordedFileCompleted& InOnUploadRecordedFileCompleted) { return -1;}
	virtual int32 DownloadRecordedFile(const FString& FileId, FDownloadRecordedFileCompleted InOnDownloadRecordedFileCompleted) { return -1;}

	//播放语音&&停止播放语音
	virtual int32 PlayRecordedFile(const FString& FilePath,const FPlayRecordedFileCompleted& PlayRecordedFileCompleted){return -1;}
	virtual int32 StopPlayFile(){return -1;}
	//获取语音文件大小&&时长
	virtual int32 GetFileSize(const FString& FilePath){return -1;}
	virtual float GetVoiceFileDuration(const FString& FilePath){return -1;}

	// 翻译自己的语音消息（离线语音转文字模式）
	virtual int32 SpeechToText(const FString& FileId,const FSpeechToTextCompleted& SpeechToTextCompleted) {return -1;}
	
	//流式语音转文本
	virtual int32 StartStreamSpeechToText(const FStreamSpeechToTextRunning& InStreamSpeechToTextRunning,
		const FStreamSpeechToTextCompleted& StreamSpeechToTextCompleted) {return -1;}
	virtual int32 StopStreamSpeechToText(){return -1;}

	//加入/退出聊天房间
	virtual int32 EnterVoiceRoom(const FString& RoomId, const FEnterRoomCompleted& EnterRoomCompleted){return -1;}
	virtual int32 ExitVoiceRoom(const FExitRoomCompleted& ExitRoomCompleted){return -1;}

	virtual int32 SWitchVoiceRoom(const FString& RoomId, const FSwitchRoomCompleted& SwitchRoomCompleted) {return -1;}

	//获取群成员列表
	virtual TArray<FString> GetVoiceRoomMemberOpenIds() const { return TArray<FString>{}; } 
	
	virtual int32 SetMicVolume(int32 Vol){return -1;};
	virtual int32 GetMicVolume(){return -1;};
	virtual int32 SetSpeakerVolume(int32 Vol) {return -1;};
	virtual int32 GetSpeakerVolume(){return -1;};
	
	virtual int32 OpenMic() { return -1; }
	virtual int32 CloseMic() { return -1; }
	virtual ECsdkMicState GetMicState() {return ECsdkMicState::Closed;}

	virtual int32 OpenSpeaker() { return -1; }
	virtual int32 CloseSpeaker() { return -1; }
	virtual ECsdkSpeakerState GetSpeakerState() {return ECsdkSpeakerState::Closed;}

	bool HasVoiceRoom() { return bHasVoiceRoom; }
	
	static TMap<FString, FUploadRecordedFileCompleted>& GetUploadCallbackMap();	
	static TMap<FString, FDownloadRecordedFileCompleted>& GetDownloadCallbackMap();
	static TMap<FString, FPlayRecordedFileCompleted>& GetPlayCallbackMap();
	static TMap<FString, FSpeechToTextCompleted>& GetSpeechToTextCallbackMap();
	static TMap<FString, FStreamSpeechToTextCompleted>& GetStreamSpeechToTextCompletedCallbackMap();
	
protected:
	virtual FString GetRecordingFileName();
	virtual FString GetDownloadFilePath();
	static FString GetFileStorePath();
	UPROPERTY()
	TObjectPtr<UCsdkVoiceSupportSubsystem> VoiceSupportSubsystem = nullptr;
protected:
	CSDK_TickerHandle TickerHandle;
	FRecordFileCompleted RecordFileCompleted;
	FStreamSpeechToTextRunning StreamSpeechToTextRunning;
	
	FString CurrentRoomId;
	FEnterRoomCompleted EnterRoomCompletedCallback;
	FExitRoomCompleted ExitRoomCompletedCallback;
	FSwitchRoomCompleted SwitchRoomCompletedCallback;
	EVoiceRoomStatus VoiceRoomStatus = EVoiceRoomStatus::NoRoom;
	
	bool bHasVoiceRoom = false;
	
};
