#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"

#include "HyperTwistCoachAssistantWidget.generated.h"

class IHttpRequest;
class UButton;
class UEditableTextBox;
class UScrollBox;
class UTextBlock;
class UVerticalBox;

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FHyperTwistCoachAssistantCloseRequestedSignature);

UCLASS(BlueprintType, Blueprintable)
class UNREALHYPERTWIST_API UHyperTwistCoachAssistantWidget : public UUserWidget
{
	GENERATED_BODY()

public:
	UHyperTwistCoachAssistantWidget(const FObjectInitializer& ObjectInitializer);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Coach")
	bool PrepareAssistantSurface();

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Coach")
	bool IsAssistantSurfaceReady() const;

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Coach")
	void SetPuzzleContext(const FString& Title, const FString& Subtitle);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Coach|Speech")
	void SubmitDictatedPrompt(
		const FString& Transcript,
		bool bSubmitImmediately
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Coach|Speech")
	void SetDictationStatus(
		const FString& Status,
		bool bRecording,
		bool bError = false
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Coach|Speech")
	void SetNarrationStatus(const FString& Status, bool bError = false);

	UPROPERTY(BlueprintAssignable, Category = "HyperTwist|Coach")
	FHyperTwistCoachAssistantCloseRequestedSignature OnCloseRequested;

protected:
	virtual TSharedRef<SWidget> RebuildWidget() override;
	virtual void NativeDestruct() override;
	virtual FReply NativeOnKeyDown(
		const FGeometry& InGeometry,
		const FKeyEvent& InKeyEvent
	) override;

private:
	void EnsureWidgetTreeBuilt();
	void AddConversationMessage(
		const FString& RoleLabel,
		const FString& Message,
		bool bUserMessage
	);
	void SubmitPrompt(const FString& Prompt);
	void BeginCoachRequest(const FString& Prompt);
	void HandleCoachResponse(
		bool bTransportSucceeded,
		int32 StatusCode,
		const FString& ResponseBody
	);
	void NarrateResponseIfEnabled(const FString& ResponseText);
	void SetStatus(const FString& Message, bool bError = false);
	FString BuildBuiltInGuideResponse(const FString& Prompt) const;
	FString BuildRequestUrl(const FString& Endpoint) const;
	FString BuildRequestBody(
		const FString& Prompt,
		bool bUseResponsesApi
	) const;
	FString ParseResponseText(
		const FString& ResponseBody,
		bool bUseResponsesApi,
		FString& OutFailureReason
	) const;

	UFUNCTION()
	void HandleSendClicked();

	UFUNCTION()
	void HandleClearClicked();

	UFUNCTION()
	void HandleDictationClicked();

	UFUNCTION()
	void HandleCloseClicked();

	UFUNCTION()
	void HandleControlsPromptClicked();

	UFUNCTION()
	void HandlePuzzlePromptClicked();

	UFUNCTION()
	void HandleSettingsPromptClicked();

	UFUNCTION()
	void HandlePromptCommitted(
		const FText& Text,
		ETextCommit::Type CommitMethod
	);

	UPROPERTY(Transient)
	TObjectPtr<UScrollBox> ConversationScroll = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UVerticalBox> ConversationList = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UEditableTextBox> PromptInput = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> ContextText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> StatusText = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UButton> DictationButton = nullptr;

	UPROPERTY(Transient)
	TObjectPtr<UTextBlock> DictationButtonLabel = nullptr;

	TSharedPtr<IHttpRequest, ESPMode::ThreadSafe> ActiveRequest;
	TArray<FString> ConversationRoles;
	TArray<FString> ConversationMessages;
	FString PuzzleTitle = TEXT("HyperTwist");
	FString PuzzleSubtitle = TEXT("Active puzzle");
	FString PendingUserPrompt;
	bool bRequestInFlight = false;
	bool bLastRequestUsedResponsesApi = false;
};
