/**
 * Spark AI Voice Chat - Unreal Engine SDK
 *
 * Actor Component for voice-to-voice AI chat.
 *
 * Usage:
 *   1. Add SparkVoiceChat component to any Actor
 *   2. Set ApiKey and Endpoint in Details panel or via code
 *   3. Call StartRecording() / StopRecordingAndSend()
 *   4. Bind to OnTranscriptReceived, OnResponseReceived, OnAudioPlayed, OnError delegates
 *
 * Requires: AudioCapture plugin enabled in your project
 */

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Sound/SoundWaveProcedural.h"
#include "AudioCaptureComponent.h"
#include "SparkVoiceChat.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTranscriptReceived, const FString&, Transcript);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnResponseReceived, const FString&, AIResponse);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnAudioPlayed);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnVoiceChatError, const FString&, ErrorMessage);

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class USparkVoiceChat : public UActorComponent
{
	GENERATED_BODY()

public:
	USparkVoiceChat();

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spark AI")
	FString ApiKey;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spark AI")
	FString Endpoint = TEXT("https://your-app.vercel.app/api/voice-chat");

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spark AI")
	FString SessionId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spark AI")
	int32 SampleRate = 16000;

	// Delegates
	UPROPERTY(BlueprintAssignable, Category = "Spark AI|Events")
	FOnTranscriptReceived OnTranscriptReceived;

	UPROPERTY(BlueprintAssignable, Category = "Spark AI|Events")
	FOnResponseReceived OnResponseReceived;

	UPROPERTY(BlueprintAssignable, Category = "Spark AI|Events")
	FOnAudioPlayed OnAudioPlayed;

	UPROPERTY(BlueprintAssignable, Category = "Spark AI|Events")
	FOnVoiceChatError OnError;

	UFUNCTION(BlueprintCallable, Category = "Spark AI")
	void StartRecording();

	UFUNCTION(BlueprintCallable, Category = "Spark AI")
	void StopRecordingAndSend();

	UFUNCTION(BlueprintCallable, Category = "Spark AI")
	bool IsRecording() const { return bIsRecording; }

protected:
	virtual void BeginPlay() override;

private:
	bool bIsRecording = false;
	TArray<float> RecordedSamples;

	UPROPERTY()
	UAudioCaptureComponent* AudioCapture;

	void OnAudioGenerate(const float* InAudio, int32 NumSamples);
	void SendVoiceChat(const TArray<uint8>& WavData);
	void OnHttpResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bSuccess);
	TArray<uint8> EncodeToWav(const TArray<float>& Samples, int32 Channels, int32 Rate);
	void PlayWavResponse(const TArray<uint8>& WavData);

	FString GenerateSessionId() const;
};
