#ifndef ABILITYEXPORT_H
#define ABILITYEXPORT_H
#include <regex>
#include <string>
#include <vector>
#include <json_struct/json_struct.h>

#include "ScopedEnumBitwiseOperators.h"

using namespace std;

enum class AbilityTypeFlags {
    Debuff = 1,
    Buff = 2,
    AE = 4,
    AEEncounterHostile,
    SingleTargetBeneficial = 16,
    SingleTargetHostile = 32,
    Daze = 64,
    Stun = 128,
    Fear = 256,
    Root = 512,
    Snare = 1024,
    Interrupt = 2048,
    Cure = 4096,
    GroupBeneficial = 8192,
    RaidBeneficial = 16384,
    SelfBeneficial = 32768,
    Damage = 65536,
    Self = 131072,
};

enum class AbilityRequirementsFlags {
    NoEpic = 1,
    Flanking = 2,
    Stealth = 4,
    Ranged = 8,
};

JS_ENUM_DECLARE_VALUE_PARSER(AbilityTypeFlags);
JS_ENUM_DECLARE_VALUE_PARSER(AbilityRequirementsFlags);

struct ExportedAbility {
    unsigned long Id;
    string Name;
    string Description;
    string Tier;
    unsigned int Level;
    int HealthCost;
    int PowerCost;
    int DissonanceCost;
    int SavageryCost;
    int ConcentrationCost;
    int MainIconID;
    int HOIconID;
    float CastingTime;
    float RecoveryTime;
    float RecastTime;
    float MaxDuration;
    int NumClasses;
    int NumEffects;
    int BackdropIconID;
    int HealthCostPerTick;
    int PowerCostPerTick;
    int DissonanceCostPerTick;
    int SavageryCostPerTick;
    int MaxAOETargets;
    int DoesNotExpire;
    int GroupRestricted;
    int AllowRaid;
    int IsBeneficial;
    float EffectRadius;
    int TargetType;
    int SpellBookType;
    float MinRange;
    float MaxRange;
    unsigned int Damage;
    vector<string> Effects;
    AbilityTypeFlags TypeFlags;
    AbilityRequirementsFlags RequirementsFlags;

    JS_OBJ(Id, Name, Description, Tier, Level, HealthCost, PowerCost, DissonanceCost, SavageryCost, ConcentrationCost,
           MainIconID, HOIconID, CastingTime, RecoveryTime, RecastTime, MaxDuration, NumClasses, NumEffects,
           BackdropIconID, HealthCostPerTick, PowerCostPerTick, DissonanceCostPerTick, SavageryCostPerTick,
           MaxAOETargets, DoesNotExpire, GroupRestricted, AllowRaid, IsBeneficial, EffectRadius, TargetType,
           SpellBookType, MinRange, MaxRange, Damage, Effects, TypeFlags, RequirementsFlags);
};


/// \brief Strips trailing roman numerals from a string
/// \details This function is used to strip trailing roman numerals from a string.  For example, "Ability I" would be
///     returned as "Ability".  "Ability II" would be returned as "Ability".
/// \param name The name to strip trailing roman numerals from
/// \return The name with trailing roman numerals stripped
inline string StripTrailingRomanNumerals(const string &name) {
    // Regex to match trailing Roman numerals and whitespace
    const std::regex romanNumeralRegex(R"(\s*(M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3}))\s*$)");

    // Replace the matched trailing Roman numerals and whitespace with an empty string
    return std::regex_replace(name, romanNumeralRegex, "");
}


#endif //ABILITYEXPORT_H
