package net.minecraft.world.level.storage.loot.functions;

import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.util.GsonHelper;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonObject;
import net.minecraft.resources.ResourceLocation;
import org.apache.logging.log4j.LogManager;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import java.util.Locale;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import net.minecraft.world.level.Level;
import net.minecraft.world.item.MapItem;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.core.BlockPos;
import com.google.common.collect.ImmutableSet;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParam;
import java.util.Set;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraft.world.level.saveddata.maps.MapDecoration;
import org.apache.logging.log4j.Logger;

public class ExplorationMapFunction extends LootItemConditionalFunction {
    private static final Logger LOGGER;
    public static final MapDecoration.Type DEFAULT_DECORATION;
    private final String destination;
    private final MapDecoration.Type mapDecoration;
    private final byte zoom;
    private final int searchRadius;
    private final boolean skipKnownStructures;
    
    private ExplorationMapFunction(final LootItemCondition[] arr, final String string, final MapDecoration.Type a, final byte byte4, final int integer, final boolean boolean6) {
        super(arr);
        this.destination = string;
        this.mapDecoration = a;
        this.zoom = byte4;
        this.searchRadius = integer;
        this.skipKnownStructures = boolean6;
    }
    
    @Override
    public Set<LootContextParam<?>> getReferencedContextParams() {
        return ImmutableSet.of(LootContextParams.BLOCK_POS);
    }
    
    public ItemStack run(final ItemStack ben, final LootContext crx) {
        if (ben.getItem() != Items.MAP) {
            return ben;
        }
        final BlockPos fk4 = crx.<BlockPos>getParamOrNull(LootContextParams.BLOCK_POS);
        if (fk4 != null) {
            final ServerLevel xd5 = crx.getLevel();
            final BlockPos fk5 = xd5.findNearestMapFeature(this.destination, fk4, this.searchRadius, this.skipKnownStructures);
            if (fk5 != null) {
                final ItemStack ben2 = MapItem.create(xd5, fk5.getX(), fk5.getZ(), this.zoom, true, true);
                MapItem.renderBiomePreviewMap(xd5, ben2);
                MapItemSavedData.addTargetDecoration(ben2, fk5, "+", this.mapDecoration);
                ben2.setHoverName(new TranslatableComponent("filled_map." + this.destination.toLowerCase(Locale.ROOT), new Object[0]));
                return ben2;
            }
        }
        return ben;
    }
    
    public static Builder makeExplorationMap() {
        return new Builder();
    }
    
    static {
        LOGGER = LogManager.getLogger();
        DEFAULT_DECORATION = MapDecoration.Type.MANSION;
    }
    
    public static class Builder extends LootItemConditionalFunction.Builder<Builder> {
        private String destination;
        private MapDecoration.Type mapDecoration;
        private byte zoom;
        private int searchRadius;
        private boolean skipKnownStructures;
        
        public Builder() {
            this.destination = "Buried_Treasure";
            this.mapDecoration = ExplorationMapFunction.DEFAULT_DECORATION;
            this.zoom = 2;
            this.searchRadius = 50;
            this.skipKnownStructures = true;
        }
        
        @Override
        protected Builder getThis() {
            return this;
        }
        
        public Builder setDestination(final String string) {
            this.destination = string;
            return this;
        }
        
        public Builder setMapDecoration(final MapDecoration.Type a) {
            this.mapDecoration = a;
            return this;
        }
        
        public Builder setZoom(final byte byte1) {
            this.zoom = byte1;
            return this;
        }
        
        public Builder setSkipKnownStructures(final boolean boolean1) {
            this.skipKnownStructures = boolean1;
            return this;
        }
        
        @Override
        public LootItemFunction build() {
            return new ExplorationMapFunction(this.getConditions(), this.destination, this.mapDecoration, this.zoom, this.searchRadius, this.skipKnownStructures, null);
        }
    }
    
    public static class Serializer extends LootItemConditionalFunction.Serializer<ExplorationMapFunction> {
        protected Serializer() {
            super(new ResourceLocation("exploration_map"), ExplorationMapFunction.class);
        }
        
        @Override
        public void serialize(final JsonObject jsonObject, final ExplorationMapFunction ctd, final JsonSerializationContext jsonSerializationContext) {
            super.serialize(jsonObject, ctd, jsonSerializationContext);
            if (!ctd.destination.equals("Buried_Treasure")) {
                jsonObject.add("destination", jsonSerializationContext.serialize(ctd.destination));
            }
            if (ctd.mapDecoration != ExplorationMapFunction.DEFAULT_DECORATION) {
                jsonObject.add("decoration", jsonSerializationContext.serialize(ctd.mapDecoration.toString().toLowerCase(Locale.ROOT)));
            }
            if (ctd.zoom != 2) {
                jsonObject.addProperty("zoom", ctd.zoom);
            }
            if (ctd.searchRadius != 50) {
                jsonObject.addProperty("search_radius", ctd.searchRadius);
            }
            if (!ctd.skipKnownStructures) {
                jsonObject.addProperty("skip_existing_chunks", ctd.skipKnownStructures);
            }
        }
        
        @Override
        public ExplorationMapFunction deserialize(final JsonObject jsonObject, final JsonDeserializationContext jsonDeserializationContext, final LootItemCondition[] arr) {
            String string5 = jsonObject.has("destination") ? GsonHelper.getAsString(jsonObject, "destination") : "Buried_Treasure";
            string5 = (Feature.STRUCTURES_REGISTRY.containsKey(string5.toLowerCase(Locale.ROOT)) ? string5 : "Buried_Treasure");
            final String string6 = jsonObject.has("decoration") ? GsonHelper.getAsString(jsonObject, "decoration") : "mansion";
            MapDecoration.Type a7 = ExplorationMapFunction.DEFAULT_DECORATION;
            try {
                a7 = MapDecoration.Type.valueOf(string6.toUpperCase(Locale.ROOT));
            }
            catch (IllegalArgumentException illegalArgumentException8) {
                ExplorationMapFunction.LOGGER.error("Error while parsing loot table decoration entry. Found {}. Defaulting to " + ExplorationMapFunction.DEFAULT_DECORATION, string6);
            }
            final byte byte8 = GsonHelper.getAsByte(jsonObject, "zoom", (byte)2);
            final int integer9 = GsonHelper.getAsInt(jsonObject, "search_radius", 50);
            final boolean boolean10 = GsonHelper.getAsBoolean(jsonObject, "skip_existing_chunks", true);
            return new ExplorationMapFunction(arr, string5, a7, byte8, integer9, boolean10, null);
        }
    }
}
