#ifndef FORWHO_H
#define FORWHO_H
#include <algorithm>
#include <string>
#include <ranges>

#include "isxeq2/ExtensionTLOs.h"

inline bool IsForMe(const std::string &forWho);

inline bool IsForMe(const std::string &command, const std::string &parameter);

inline bool IsForMe(const std::string &command, const std::string &parameter) {
    string commandLower(command);
    string parameterLower(parameter);
    string me = ExtensionTLOs::Me().Name();
    string className = ExtensionTLOs::Me().Class();
    string subClassName = ExtensionTLOs::Me().SubClass();
    string archetypeName = ExtensionTLOs::Me().Archetype();
    vector<string> groupMembers;
    vector<string> raidMembers;

    for (int idx = 0; idx <= ExtensionTLOs::Me().GroupCount(); ++idx) {
        string name = ExtensionTLOs::Me().GroupMemberByIndex(idx).Name();
        ranges::transform(name, name.begin(), ::tolower);
        groupMembers.push_back(name);
    }

    for (int idx = 1; idx <= 24; idx++) {
        // I don't know how to tell if it's valid or not, not sure what NULL will look like
        auto name = ExtensionTLOs::Me().RaidMemberByIndex(idx).Name();
        ranges::transform(name, name.begin(), ::tolower);
        raidMembers.push_back(name);
    }

    ranges::transform(commandLower, commandLower.begin(), ::tolower);
    ranges::transform(parameterLower, parameterLower.begin(), ::tolower);
    ranges::transform(me, me.begin(), ::tolower);
    ranges::transform(className, className.begin(), ::tolower);
    ranges::transform(subClassName, subClassName.begin(), ::tolower);
    ranges::transform(archetypeName, archetypeName.begin(), ::tolower);

    if (commandLower == "igw") {
        return ranges::find(groupMembers, parameterLower) != groupMembers.end();
    }

    if (commandLower == "igwbn") {
        auto view = groupMembers | std::views::drop(1);
        return ranges::find(view, parameterLower) == groupMembers.end();
    }

    if (commandLower == "irw") {
        return ranges::find(raidMembers, parameterLower) != raidMembers.end();
    }

    if (commandLower == "irwbn") {
        auto view = raidMembers | std::views::drop(1);
        return ranges::find(view, parameterLower) == raidMembers.end();
    }

    if (commandLower == "not") {
        return !IsForMe(parameterLower);
    }

    return true;
}

inline bool IsForMe(const std::string &forWho) {
    string forWhoLower(forWho);
    string me = ExtensionTLOs::Me().Name();
    string className = ExtensionTLOs::Me().Class();
    string subClassName = ExtensionTLOs::Me().SubClass();
    string archetypeName = ExtensionTLOs::Me().Archetype();
    ranges::transform(forWhoLower, forWhoLower.begin(), ::tolower);
    ranges::transform(me, me.begin(), ::tolower);
    ranges::transform(className, className.begin(), ::tolower);
    ranges::transform(subClassName, subClassName.begin(), ::tolower);
    ranges::transform(archetypeName, archetypeName.begin(), ::tolower);

    if (forWhoLower == "all" || forWhoLower == me) {
        return true;
    }

    if (forWhoLower == className || forWhoLower == subClassName || forWhoLower == archetypeName) {
        return true;
    }

    if (forWhoLower == "melee" && (archetypeName == "fighter" || archetypeName == "scout")) {
        return true;
    }

    if (forWhoLower == "caster" && (archetypeName == "mage" || archetypeName == "priest")) {
        return true;
    }

    if (const auto colonIndex = forWhoLower.find(':'); colonIndex != std::string::npos) {
        const auto forWhoCommand = forWhoLower.substr(0, colonIndex);
        const auto forWhoParameter = forWhoLower.substr(colonIndex + 1);

        return IsForMe(forWhoCommand, forWhoParameter);
    }

    if (forWhoLower.starts_with("not")) {
        return !IsForMe(forWhoLower.substr(3));
    }

    return false;
}

#endif //FORWHO_H
