public void HandleDamage(int damageAmount, LivingEntity attacker, LivingEntity victim, bool playVFXInstantly = false, AbilityDataSO.AttackType attackType = AbilityDataSO.AttackType.None, AbilityDataSO.DamageType damageType = AbilityDataSO.DamageType.None)
    {
        int blockAfter  = victim.currentBlock;
        int healthAfter = victim.currentHealth;

        if (victim.currentBlock == 0)
        {
            healthAfter = victim.currentHealth - damageAmount;
            blockAfter  = 0;
        }
        else if (victim.currentBlock > 0)
        {
            blockAfter = victim.currentBlock;
            Debug.Log("block after = " + blockAfter);
            blockAfter = blockAfter - damageAmount;
            Debug.Log("block after = " + blockAfter);
            if (blockAfter < 0)
            {
                healthAfter  = victim.currentHealth;
                healthAfter += blockAfter;
                blockAfter   = 0;
                Debug.Log("block after = " + blockAfter);
            }
        }

        if (victim.hasBarrier && healthAfter < victim.currentHealth)
        {
            damageAmount = 0;
            healthAfter  = victim.currentHealth;
            victim.ModifyCurrentBarrierStacks(-1);
        }

        // Poisonous trait
        if (attacker.myPassiveManager.Poisonous && healthAfter < victim.currentHealth)
        {
            victim.ModifyPoison(attacker.myPassiveManager.poisonousStacks);
        }

        // Remove sleeping
        if (victim.isSleeping && damageAmount > 0)
        {
            Debug.Log("Damage taken, removing sleep");
            victim.ModifySleeping(-victim.currentSleepingStacks);
        }

        // Enrage
        if (victim.myPassiveManager.Enrage && healthAfter < victim.currentHealth)
        {
            Debug.Log("Enrage triggered, gaining strength");
            victim.ModifyCurrentStrength(victim.myPassiveManager.enrageStacks);
        }

        if (victim.myPassiveManager.Adaptive && healthAfter < victim.currentHealth)
        {
            Debug.Log("Adaptive triggered, gaining block");
            victim.ModifyCurrentBlock(victim.myPassiveManager.adaptiveStacks);
        }

        // remove camoflage if damaged
        if (victim.isCamoflaged && healthAfter < victim.currentHealth)
        {
            victim.RemoveCamoflage();
        }

        victim.currentHealth     = healthAfter;
        victim.currentBlock      = blockAfter;
        victim.myHealthBar.value = victim.CalculateHealthBarPosition();
        victim.UpdateCurrentHealthText();


        victim.SetCurrentBlock(victim.currentBlock);

        if (damageAmount > 0)
        {
            StartCoroutine(VisualEffectManager.Instance.CreateDamageEffect(victim.transform.position, damageAmount, playVFXInstantly));
        }

        if (victim.myPassiveManager.Thorns)
        {
            // TO DO: this needs be updated when we implement damage and attack types
            // if two characters with thorns attack each other, they will continously thorns damage each other until 1 dies
            // thorns damage can only be triggered by a melee attack
            if (attackType == AbilityDataSO.AttackType.Melee)
            {
                HandleDamage(CalculateDamage(victim.myPassiveManager.thornsStacks, victim, attacker, AbilityDataSO.DamageType.None), attacker, victim);
            }
        }

        if (victim.myPassiveManager.LightningShield)
        {
            // TO DO: this needs be updated when we implement damage and attack types
            // if two characters with thorns attack each other, they will continously thorns damage each other until 1 dies
            // thorns damage can only be triggered by a melee attack
            HandleDamage(CalculateDamage(victim.myPassiveManager.lightningShieldStacks, victim, attacker, AbilityDataSO.DamageType.Magic), attacker, victim);
        }

        if (victim.timesAttackedThisTurn == 0 && victim.myPassiveManager.QuickReflexes && victim.IsAbleToMove())
        {
            StartCoroutine(VisualEffectManager.Instance.CreateStatusEffect(victim.transform.position, "Quick Reflexes", true));
            StartCoroutine(victim.StartQuickReflexesMove());
        }
        victim.timesAttackedThisTurn++;

        if (victim.currentHealth <= 0)
        {
            StartCoroutine(victim.HandleDeath());
        }
    }