/*
 * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
 * and/or modify it under version 3 of the License, or (at your option), any later version.
 */

#ifndef _PLAYERBOT_STATSCOLLECTOR_H
#define _PLAYERBOT_STATSCOLLECTOR_H

#include "ItemTemplate.h"
#include "SpellInfo.h"

enum StatsType : uint8
{
    // Basic stats
    STATS_TYPE_AGILITY = 0,
    STATS_TYPE_STRENGTH,
    STATS_TYPE_INTELLECT,
    STATS_TYPE_SPIRIT,
    STATS_TYPE_STAMINA,
    STATS_TYPE_HIT,
    STATS_TYPE_CRIT,
    STATS_TYPE_HASTE,
    // Stats for tank
    STATS_TYPE_ARMOR,
    STATS_TYPE_DEFENSE,
    STATS_TYPE_DODGE,
    STATS_TYPE_PARRY,
    STATS_TYPE_BLOCK_VALUE,
    STATS_TYPE_BLOCK_RATING,
    STATS_TYPE_RESILIENCE,
    STATS_TYPE_HEALTH_REGENERATION,
    // Stats for spell damage
    STATS_TYPE_SPELL_POWER,
    STATS_TYPE_SPELL_PENETRATION,
    // Stats for heal
    STATS_TYPE_HEAL_POWER,
    STATS_TYPE_MANA_REGENERATION,
    // Stats for physical damage and melee
    STATS_TYPE_ATTACK_POWER,
    STATS_TYPE_ARMOR_PENETRATION,
    STATS_TYPE_EXPERTISE,
    // Stats for weapon dps
    STATS_TYPE_MELEE_DPS,
    STATS_TYPE_RANGED_DPS,
    // Bonus for unrecognized stats
    STATS_TYPE_BONUS,
    STATS_TYPE_MAX = 26
};

enum CollectorType : uint8
{
    MELEE_DMG = 1,
    MELEE_TANK = 2,
    RANGED = 4,
    SPELL_DMG = 8,
    SPELL_HEAL = 16,
    MELEE = MELEE_DMG | MELEE_TANK,
    SPELL = SPELL_DMG | SPELL_HEAL
};

class StatsCollector
{
public:
    StatsCollector(CollectorType type, int32 cls = -1);
    StatsCollector(StatsCollector& stats) = default;
    void Reset();
    void CollectItemStats(ItemTemplate const* proto);
    void CollectSpellStats(uint32 spellId, float multiplier = 1.0f, Milliseconds spellCooldown = -1ms);
    void CollectEnchantStats(SpellItemEnchantmentEntry const* enchant, uint32 default_enchant_amount = 0);
    bool CanBeTriggeredByType(SpellInfo const* spellInfo, uint32 procFlags, bool strict = true);
    bool CheckSpellValidation(uint32 spellFamilyName, flag96 spelFalimyFlags, bool strict = true);

public:
    float stats[STATS_TYPE_MAX];

private:
    void CollectByItemStatType(uint32 itemStatType, int32 val);
    bool SpecialSpellFilter(uint32 spellId);
    bool SpecialEnchantFilter(uint32 enchantSpellId);

    void HandleApplyAura(const SpellEffectInfo& effectInfo, float multiplier, bool canNextTrigger,
                         Milliseconds triggerCooldown);
    float AverageValue(const SpellEffectInfo& effectInfo);

private:
    CollectorType type_;
    uint32 cls_;
};

#endif
