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

#pragma once

#include "CoreMinimal.h"
#include "Components/Button.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
#include "StatusEffect.h"
#include "NiagaraFunctionLibrary.h"
#include "GameFramework/GameStateBase.h"
#include "Components/WidgetComponent.h"
#include "Engine/PostProcessVolume.h"
#include "TurnBaseCombatV2.generated.h"

class UNiagaraSystem;

UCLASS()
class THE_TWILIGHT_ABYSS_API ATurnBaseCombatV2 : public AGameStateBase
{
	GENERATED_BODY()

public:
	ATurnBaseCombatV2();

	int* EnemyHealth = nullptr;
	float* PlayerHealth = nullptr;
	bool bIsInCombat = false;

	UPROPERTY(EditDefaultsOnly)
	float BaseDamageMultiplier = 1.0f;
	UPROPERTY(EditDefaultsOnly)
	float BaseDefenseMultiplier = 1.0f;
	UPROPERTY()
	float ChainDamageMultiplier = 0;
	UPROPERTY(EditAnywhere)
	float ChainDamageMultiplierIncrease = 0.2f;
	
	UPROPERTY(EditDefaultsOnly)
	int DefaultActionPoints = 2;
	UPROPERTY()
	int ActiveActionPoints = 0;
	
	UPROPERTY(EditDefaultsOnly)
	int ProbertiumResource = 10; 
	UPROPERTY(EditDefaultsOnly)
	int EisResource = 10;
	UPROPERTY(EditDefaultsOnly)
	int AzosResource = 10;
	UPROPERTY(EditDefaultsOnly)
	int IroquoidResource = 10;

	UPROPERTY(EditDefaultsOnly)
	UNiagaraSystem* GunEffect;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	UMaterialInstanceDynamic* RedVignetteMaterialInstance;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	AActor* PlayerActor;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	AActor* EnemyActor;
	// AActor* ActiveActor;
	UPROPERTY(BlueprintReadWrite)
	UUserWidget* HUD;

	UPROPERTY()
	UUserWidget* BookHUD;
	UPROPERTY()
	UUserWidget* CombatTutorialWidgetInstance;
	UPROPERTY()
	UWidgetComponent* PlayerWidget;
	
	UPROPERTY(EditAnywhere)
	TSubclassOf<UUserWidget> HUDWidget;
	UPROPERTY(EditAnywhere)
	TSubclassOf<UUserWidget> CombatTutorialWidget;
	UPROPERTY(BlueprintReadWrite)
	bool HasSeenTutorial = false;
	UPROPERTY(EditAnywhere)
	TMap<FString, int32> ValidCombos =
	{
		{"PE", 15},
		{"PA", 15},
		{"PI", 15},
		{"EA", 15},
		{"EI", 15},
		{"AI", 15},
		{"PP", 20},
		{"EE", 20},
		{"AA", 20},
		{"II", 20}
	};
	UPROPERTY(EditAnywhere)
	TMap<FString, FString> SpecialCombos =
	{
		{"PA", "Thorns"},
		{"PI", "DamageOverTime"}
	};

	FString BattleLog;

	UFUNCTION(BlueprintCallable)
	void StartCombat(AActor* Enemy, bool bWasShot = false);
	UFUNCTION(BlueprintCallable)
	void CombatCheck(bool bWasShot = false);
	UFUNCTION(BlueprintCallable)
	void EndCombat();

	DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnPlayerTurn, AActor*, AActor*);
	DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnEnemyTurn, AActor*, AActor*);
	FOnPlayerTurn OnPlayerTurn;
	FOnEnemyTurn OnEnemyTurn;

	void DamagePlayer(int Damage, const FString& DamageType = "unknown");
	void DamageEnemy(int Damage, const FString& DamageType = "unknown");
	
protected:
	virtual void BeginPlay() override;
	void ExecuteCast(FString Combo);
	void UseActionPoint();
	void ReuseActionPoint();
	void RevertActionPoints();
	void UpdateProgressBars() const;

	bool bPlayerHasExtraTurn = false;
	bool bEnemyHasExtraTurn = false;

	float EscapePercentage = 0.0f;
	float CalculateEscapePercentage() const;

private:
	bool IsValidCombo(const FString& Combo) const;
	bool IsSpecialCombo(const FString& Combo) const;

	UPROPERTY()
	APostProcessVolume* PostProcessVolume;

	UPROPERTY()
	TSubclassOf<UStatusEffect> ThornsStatusEffect;
	UPROPERTY()
	TSubclassOf<UStatusEffect> DOTStatusEffect;

	UPROPERTY()
	TArray<UStatusEffect*> StatusEffects;

	UPROPERTY(VisibleAnywhere)
	bool bIsPlayerTurn = true;

	FString PreviousComboString = "";

	UPROPERTY(VisibleAnywhere)
	FString CurrentComboString = "";

	void SwitchTurn();

	UPROPERTY()
	UTextBlock* TurnIndicatorTextBlock;
	UPROPERTY()
	UTextBlock* CurrentComboTextBlock;
	UPROPERTY()
	UTextBlock* CurrentComboTextBlock1;
	UPROPERTY()
	UTextBlock* CurrentComboTextBlock2;
	UPROPERTY()
	UTextBlock* BattleLogTextBlock;
	UPROPERTY()
	UTextBlock* EscapePercentageTextBlock;
	UPROPERTY()
	UTextBlock* DamageMultiplierTextBlock;
	UPROPERTY()
	UTextBlock* HealingJellyAmountTextBlock;
	UPROPERTY()
	UTextBlock* DamageAmountEnemyTextBlock;
	UPROPERTY()
	UTextBlock* DamageAmountPlayerTextBlock;
	UPROPERTY()
	UTextBlock* StatusTextBlock;

	UPROPERTY()
	UProgressBar* PlayerHealthBar;
	UPROPERTY()
	UProgressBar* EnemyHealthBar;

	UPROPERTY()
	UProgressBar* ProbertiumResourceBar;
	UPROPERTY()
	UProgressBar* EisResourceBar;
	UPROPERTY()
	UProgressBar* AzosResourceBar;
	UPROPERTY()
	UProgressBar* IroquoidResourceBar;

	UPROPERTY()
	UButton* CastButton;

	UPROPERTY()
	UButton* PButton;
	UPROPERTY()
	UButton* EButton;
	UPROPERTY()
	UButton* AButton;
	UPROPERTY()
	UButton* IButton;

	UPROPERTY()
	UButton* BackspaceButton;
	UPROPERTY()
	UButton* RunButton;
	UPROPERTY()
	UButton* HealButton;

	UFUNCTION()
	void CastButtonOnClick();

	UFUNCTION()
	void PButtonOnClick();
	UFUNCTION()
	void EButtonOnClick();
	UFUNCTION()
	void AButtonOnClick();
	UFUNCTION()
	void IButtonOnClick();

	UFUNCTION()
	void BackspaceButtonOnClick();
	UFUNCTION()
	void RunButtonOnClick();
	UFUNCTION()
	void HealButtonOnClick();

	void UpdateComboString(const FString& NewCombo) const;
	static void UpdateActionPoints();

	void AddBattleLogMessage(const FString& Message);
	void ClearBattleLog();
	void UpdateBattleLog();
	void UpdateResourceBars() const;
	UFUNCTION(BlueprintCallable)
	void DisableButtons() const;
	UFUNCTION(BlueprintCallable)
	void EnableButtons() const;
	void EnemyTurn();
	UFUNCTION(BlueprintCallable)
	void ToggleButtonIfResourceAvailable() const;

	UPROPERTY()
	UUserWidget* DeathScreenWidget;
	UPROPERTY()
	TSubclassOf<UUserWidget> DeathScreenWidgetSubclass;
	UPROPERTY()
	UStaticMeshComponent* BookStaticMeshComponent;
};