Why my tree not respawning. Im getting the timer being set in Debug after tree disapears but nothing after?

#include "Actors/ClickableActors/Skilling/TreeBase/TreeBase.h"
#include "Components/StaticMeshComponent.h"
#include "BMM/BMMCharacter.h"
#include "Net/UnrealNetwork.h"
#include "Engine/Engine.h"
#include "Game/AbilitySystem/ResourceAttributSet/ResourceAttributeSet.h"
#include "Input/TimedInteractable.h"
#include "AbilitySystemInterface.h"
#include "AbilitySystemComponent.h"
#include "GameplayEffect.h"
#include "GameplayEffectTypes.h"

ATreeBase::ATreeBase() :
TreeHealth(100.0f),
MaxTreeHealth(100.0f),
MaxInteractionDistance(200.0f),
RespawnTime(5.0f),
InteractingPlayerCharacter(nullptr)  // Default values and initialize player reference
{
    PrimaryActorTick.bCanEverTick = true;
    TreeMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TreeMesh"));
    RootComponent = TreeMesh;
    bIsAxe = false;
    RequiredWoodcuttingLevel = 1;
    LogsGiven = 1;
    ExperienceGiven = 10;
    LogType = "DefaultLog";  // Default log type
    bIsChoppedDown = false;

    bReplicates = true;
    SetReplicateMovement(true);

    AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
    ResourceAttributes = CreateDefaultSubobject<UResourceAttributeSet>(TEXT("ResourceAttributes"));
    ResourceAttributes->Health.SetCurrentValue(TreeHealth);
    ResourceAttributes->MaxHealth.SetCurrentValue(MaxTreeHealth);
}

void ATreeBase::BeginPlay()
{
    Super::BeginPlay();
    UE_LOG(LogTemp, Log, TEXT("Tree spawned: %s"), *GetName());
    ResourceAttributes->Health.SetCurrentValue(TreeHealth);
    ResourceAttributes->MaxHealth.SetCurrentValue(MaxTreeHealth);
}

UAbilitySystemComponent* ATreeBase::GetAbilitySystemComponent() const
{
    return nullptr;  // Return the appropriate AbilitySystemComponent instance if needed
}

void ATreeBase::StartRespawnTimer()
{
    if (HasAuthority())
    {
        GetWorldTimerManager().SetTimer(RespawnTimerHandle, this, &ATreeBase::RespawnTree, RespawnTime, false);
        UE_LOG(LogTemp, Log, TEXT("Respawn timer set for %f seconds"), RespawnTime);
    }
}

void ATreeBase::ChopDownTree(ABMMCharacter* PlayerCharacter)
{
    if (!bIsChoppedDown && HasAuthority() && PlayerCharacter && PlayerCharacter->SkillAttributeSet->WoodcuttingLevel.GetCurrentValue() >= RequiredWoodcuttingLevel)
    {
        StartRespawnTimer();
        bIsChoppedDown = true;
        UE_LOG(LogTemp, Log, TEXT("Tree being chopped down: %s by %s"), *GetName(), *PlayerCharacter->GetName());
        Interact(PlayerCharacter);
    }
    else if (bIsChoppedDown)
    {
        UE_LOG(LogTemp, Warning, TEXT("Tree is already chopped down: %s"), *GetName());
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("Player %s does not meet the required woodcutting level: %d"), *PlayerCharacter->GetName(), RequiredWoodcuttingLevel);
    }
}

void ATreeBase::HandleInteractTimerExpiry(ABMMCharacter* PlayerCharacter)
{
    UE_LOG(LogTemp, Log, TEXT("HandleInteractTimerExpiry called for: %s"), *GetName());

    if (HasAuthority() && PlayerCharacter)
    {
        UE_LOG(LogTemp, Log, TEXT("Destroying tree: %s"), *GetName());
        PlayerCharacter->UnfreezePlayer(); // Unfreeze the player when the tree is destroyed
        StopChopTreeAnimation(PlayerCharacter); // Stop the chopping animation
        StopDamageTimer(); // Stop the damage timer

        StartRespawnTimer();

        UE_LOG(LogTemp, Log, TEXT("Tree %s will respawn in %f seconds"), *GetName(), RespawnTime);

        TreeMesh->SetVisibility(false, true);
        TreeMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("PlayerCharacter is null or not authoritative"));
    }
}

void ATreeBase::ApplyDamage()
{
    float DamageAmount = 10.0f;  // Default damage amount

    const float OldHealth = ResourceAttributes->Health.GetCurrentValue();
    const float NewHealth = OldHealth - DamageAmount;
    ResourceAttributes->Health.SetCurrentValue(NewHealth);

    GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Hit Tree for %f Damage - Tree Health %f/%f"), DamageAmount, NewHealth, MaxTreeHealth));

    if (NewHealth <= 0.0f)
    {
        GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Tree has been destroyed!"));
        if (InteractingPlayerCharacter)
        {
            UE_LOG(LogTemp, Log, TEXT("Unfreezing Interacting Player: %s"), *InteractingPlayerCharacter->GetName());
            InteractingPlayerCharacter->UnfreezePlayer(); // Unfreeze the player when the tree is destroyed
        }

        StartRespawnTimer();

        UE_LOG(LogTemp, Log, TEXT("Tree %s will respawn in %f seconds"), *GetName(), RespawnTime);

        TreeMesh->SetVisibility(false, true);
        TreeMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);

        // Destroy the actor to handle proper cleanup
        Destroy();
    }
}

void ATreeBase::RespawnTree()
{
    UE_LOG(LogTemp, Log, TEXT("Respawning tree: %s"), *GetName());

    if (!HasAuthority())
    {
        UE_LOG(LogTemp, Error, TEXT("RespawnTree called on non-authoritative actor: %s"), *GetName());
        return;
    }

    // Use AActorSpawner to spawn the new tree actor
    FVector SpawnLocation = GetActorLocation();
    FRotator SpawnRotation = GetActorRotation();
    ATreeBase* NewTree = GetWorld()->SpawnActor<ATreeBase>(GetClass(), SpawnLocation, SpawnRotation);

    if (NewTree)
    {
        NewTree->TreeHealth = MaxTreeHealth;
        NewTree->ResourceAttributes->Health.SetCurrentValue(MaxTreeHealth);
        NewTree->bIsChoppedDown = false;

        NewTree->TreeMesh->SetVisibility(true);
        NewTree->TreeMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
        NewTree->TreeMesh->SetCollisionResponseToAllChannels(ECR_Block);

        NewTree->bReplicates = true;
        NewTree->SetReplicateMovement(true);

        UE_LOG(LogTemp, Log, TEXT("Tree respawned and is now visible and interactable: %s"), *NewTree->GetName());
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Failed to respawn tree: %s"), *GetName());
    }
}

void ATreeBase::Server_RespawnTree_Implementation()
{
    RespawnTree();
}

bool ATreeBase::Server_RespawnTree_Validate()
{
    return true;
}

void ATreeBase::PlayChopTreeAnimation(ABMMCharacter* PlayerCharacter)
{
    if (PlayerCharacter)
    {
        if (UAnimInstance* AnimInstance = PlayerCharacter->GetMesh()->GetAnimInstance())
        {
            if (PlayerCharacter->ChopTreeAnimation)
            {
                AnimInstance->Montage_Play(PlayerCharacter->ChopTreeAnimation);
            }
        }
    }
}

void ATreeBase::StopChopTreeAnimation(ABMMCharacter* PlayerCharacter)
{
    if (PlayerCharacter)
    {
        if (UAnimInstance* AnimInstance = PlayerCharacter->GetMesh()->GetAnimInstance())
        {
            if (PlayerCharacter->ChopTreeAnimation)
            {
                AnimInstance->Montage_Stop(0.2f, PlayerCharacter->ChopTreeAnimation);
            }
        }
    }
}

void ATreeBase::StartDamageTimer()
{
    GetWorld()->GetTimerManager().SetTimer(DamageTimerHandle, this, &ATreeBase::ApplyDamage, 0.4f, true, 0.0f);  // 4 ticks
}

void ATreeBase::StopDamageTimer()
{
    GetWorld()->GetTimerManager().ClearTimer(DamageTimerHandle);
}

void ATreeBase::ServerApplyDamage_Implementation(float DamageAmount)
{
    ApplyDamage();
}

float ATreeBase::GetHealth() const
{
    return ResourceAttributes->Health.GetCurrentValue();
}

void ATreeBase::SetHealth(float NewHealth)
{
    TreeHealth = NewHealth;
    ResourceAttributes->Health.SetCurrentValue(NewHealth);
}

float ATreeBase::GetMaxHealth() const
{
    return ResourceAttributes->MaxHealth.GetCurrentValue();
}

void ATreeBase::SetMaxHealth(float NewMaxHealth)
{
    MaxTreeHealth = NewMaxHealth;
    ResourceAttributes->MaxHealth.SetCurrentValue(NewMaxHealth);
}

bool ATreeBase::ServerApplyDamage_Validate(float DamageAmount)
{
    return true;  // Optionally, add validation logic here
}

void ATreeBase::OnRep_Health()
{
    // Log the replicated health value
    UE_LOG(LogTemp, Log, TEXT("OnRep_Health called. New Health: %f"), TreeHealth);

    // Check if health is zero and handle destruction
    if (TreeHealth <= 0.0f)
    {
        HandleInteractTimerExpiry(nullptr);
    }
}

void ATreeBase::OnRep_IsChoppedDown()
{
    if (bIsChoppedDown)
    {
        StartRespawnTimer();
        UE_LOG(LogTemp, Log, TEXT("Tree %s will respawn in %f seconds"), *GetName(), RespawnTime);
        TreeMesh->SetVisibility(false, true);
        TreeMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
    }
}

void ATreeBase::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    DOREPLIFETIME(ATreeBase, ResourceAttributes);
    DOREPLIFETIME(ATreeBase, RequiredWoodcuttingLevel);
    DOREPLIFETIME(ATreeBase, LogsGiven);
    DOREPLIFETIME(ATreeBase, ExperienceGiven);
    DOREPLIFETIME(ATreeBase, LogType);
    DOREPLIFETIME(ATreeBase, TreeHealth);  // Replicate TreeHealth
    DOREPLIFETIME(ATreeBase, MaxTreeHealth);
    DOREPLIFETIME(ATreeBase, MaxInteractionDistance);  // Replicate MaxInteractionDistance
    DOREPLIFETIME(ATreeBase, RespawnTime);
    DOREPLIFETIME(ATreeBase, bIsChoppedDown); // Replicate bIsChoppedDown
}

void ATreeBase::AwardWoodcuttingExperience(ABMMCharacter* PlayerCharacter)
{
    if (PlayerCharacter)
    {
        UE_LOG(LogTemp, Log, TEXT("Starting to award experience"));
        if (PlayerCharacter->SkillAttributeSet)
        {
            PlayerCharacter->SkillAttributeSet->AddWoodcuttingExperience(ExperienceGiven);
            UE_LOG(LogTemp, Log, TEXT("Player %s awarded %d woodcutting experience"), *PlayerCharacter->GetName(), ExperienceGiven);

            GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Awarded %d woodcutting experience!"), ExperienceGiven));

            if (PlayerCharacter->SkillAttributeSet->WoodcuttingLevel.GetCurrentValue() > 1)  // Adjust the condition as needed
            {
                GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Level Up!"));
            }

            UE_LOG(LogTemp, Log, TEXT("Finished awarding experience"));
        }
        else
        {
            UE_LOG(LogTemp, Error, TEXT("PlayerCharacter's SkillAttributeSet is null"));
        }
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("PlayerCharacter is null"));
    }
}

void ATreeBase::Interact(ABMMCharacter* PlayerCharacter)
{
    UE_LOG(LogTemp, Log, TEXT("TreeBase: Interacting with: %s"), *GetName());

    if (PlayerCharacter)
    {
        FVector PlayerLocation = PlayerCharacter->GetActorLocation();
        FVector TreeLocation = GetActorLocation();
        float Distance = FVector::Dist(PlayerLocation, TreeLocation);

        if (Distance > MaxInteractionDistance)
        {
            UE_LOG(LogTemp, Warning, TEXT("Player %s is too far from tree %s to interact (Distance: %f, Max: %f)"), *PlayerCharacter->GetName(), *GetName(), Distance, MaxInteractionDistance);
            return;  
        }

        InteractingPlayerCharacter = PlayerCharacter;  // Store the reference to PlayerCharacter
        PlayerCharacter->FreezePlayer();  // Freeze the player when starting to chop the tree
        UE_LOG(LogTemp, Log, TEXT("Freezing Player: %s"), *PlayerCharacter->GetName());
        PlayChopTreeAnimation(PlayerCharacter);  // Play the chopping animation
        StartDamageTimer();  // Start the damage timer
    }

    Super::Interact(PlayerCharacter);  // Use the base class timer logic

    if (PlayerCharacter)
    {
        AwardWoodcuttingExperience(PlayerCharacter);
    }
}

Thanks!