package com.thebrokenrail.twine.advancement;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.thebrokenrail.twine.Twine;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.tag.Tag;
import net.minecraft.tag.TagContainers;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;

import java.util.Collections;
import java.util.List;

public class BoatCriterion extends AbstractCriterion<BoatCriterion.Conditions> {
    private static final Identifier ID = new Identifier(Twine.NAMESPACE, "boat");

    public void trigger(ServerPlayerEntity player, Block block) {
        this.test(player, conditions -> conditions.getBlock().contains(block));
    }

    @Override
    protected Conditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
        JsonElement str = obj.get("block");
        List<Block> block = null;
        if (str != null) {
            String id = str.getAsString();
            if (id.startsWith("#")) {
                Tag<Block> tag = TagContainers.instance().blocks().get(new Identifier(id.substring(1)));
                if (tag != null) {
                    block = tag.values();
                }
            } else {
                block = Collections.singletonList(Registry.BLOCK.get(new Identifier(id)));
            }
        }
        if (block == null) {
            block = Collections.singletonList(Blocks.AIR);
        }
        return new Conditions(ID, playerPredicate, block);
    }

    @Override
    public Identifier getId() {
        return ID;
    }

    static class Conditions extends AbstractCriterionConditions {
        private final List<Block> block;

        public Conditions(Identifier id, EntityPredicate.Extended playerPredicate, List<Block> block) {
            super(id, playerPredicate);
            this.block = block;
        }

        public List<Block> getBlock() {
            return block;
        }
    }
}
