package me.km.snuviscript.commands;

import java.util.UUID;
import me.hammerle.snuviscript.code.ScriptManager;
import me.km.utils.Location;
import me.km.utils.ReflectionUtils;
import me.km.utils.Utils;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.MobEntity;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.IAttribute;

public class LivingCommands {
    public static void registerFunctions(ScriptManager sm) {
        IAttribute[] attributes = new IAttribute[]{
            SharedMonsterAttributes.ARMOR, SharedMonsterAttributes.ARMOR_TOUGHNESS,
            SharedMonsterAttributes.ATTACK_DAMAGE, SharedMonsterAttributes.ATTACK_KNOCKBACK,
            SharedMonsterAttributes.ATTACK_SPEED, SharedMonsterAttributes.FLYING_SPEED,
            SharedMonsterAttributes.FOLLOW_RANGE, SharedMonsterAttributes.KNOCKBACK_RESISTANCE,
            SharedMonsterAttributes.LUCK, SharedMonsterAttributes.MAX_HEALTH,
            SharedMonsterAttributes.MOVEMENT_SPEED
        };
        for(IAttribute attribute : attributes) {
            String name = attribute.getName().substring(8).toLowerCase();
            sm.registerConsumer("living.set" + name, (sc, in) -> {
                LivingEntity liv = (LivingEntity) in[0].get(sc);
                double amount = in[1].getDouble(sc) - liv.getAttribute(attribute).getBaseValue();
                UUID uuid = new UUID(name.length(), name.hashCode());
                liv.getAttribute(attribute).removeModifier(uuid);
                liv.getAttribute(attribute).applyModifier(new AttributeModifier(uuid, name, amount, AttributeModifier.Operation.ADDITION));
            });
            sm.registerFunction("living.get" + name, (sc, in) -> {
                return ((LivingEntity) in[0].get(sc)).getAttribute(attribute).getValue();
            });
            sm.registerFunction("living.getbase" + name, (sc, in) -> {
                return ((LivingEntity) in[0].get(sc)).getAttribute(attribute).getBaseValue();
            });
        }
        sm.registerConsumer("living.removeai", (sc, in) -> {
            LivingEntity ent = (LivingEntity) in[0].get(sc);
            if(ent instanceof MobEntity) {
                MobEntity mob = (MobEntity) in[0].get(sc);
                ReflectionUtils.getGoals(mob.goalSelector).clear();
                ReflectionUtils.getGoals(mob.targetSelector).clear();
            }
        });
        sm.registerFunction("living.near", (sc, in) -> {
            Object o = in[0].get(sc);
            if(o instanceof Location) {
                return Utils.getLiving((Location) o, in[1].getDouble(sc));
            }
            return Utils.getLiving((Entity) o, in[1].getDouble(sc));
        });
    }
}
