// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.entity.entities.player.pages;

import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import java.util.concurrent.CompletionStage;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.common.util.CompletableFutureUtil;
import java.util.concurrent.Executor;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.entity.entities.Player;
import java.util.concurrent.CompletableFuture;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.modules.entity.damage.DeathComponent;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.server.core.asset.type.gameplay.DeathConfig;
import java.text.DecimalFormat;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import java.util.Collection;
import java.util.HashMap;
import java.util.ArrayList;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.modules.entity.damage.DeathItemLoss;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.Message;
import javax.annotation.Nonnull;

public class RespawnPage extends InteractiveCustomUIPage<RespawnPageEventData>
{
    @Nonnull
    private static final String UI_RESPAWN_PAGE = "Pages/RespawnPage.ui";
    @Nonnull
    private static final String ELEMENT_BUTTON_RESPAWN = "#RespawnButton";
    @Nonnull
    private static final String ELEMENT_LABEL_DEATH_REASON_TEXT_SPANS = "#DeathReason.TextSpans";
    @Nullable
    private final Message deathReason;
    private final boolean displayDataOnDeathScreen;
    private final DeathItemLoss deathItemLoss;
    private final ItemStack[] itemsLostOnDeath;
    static final /* synthetic */ boolean $assertionsDisabled;
    
    public RespawnPage(@Nonnull final PlayerRef playerRef, @Nullable final Message deathReason, final boolean displayDataOnDeathScreen, final DeathItemLoss deathItemLoss) {
        super(playerRef, CustomPageLifetime.CantClose, RespawnPageEventData.CODEC);
        this.deathReason = deathReason;
        this.displayDataOnDeathScreen = displayDataOnDeathScreen;
        this.deathItemLoss = deathItemLoss;
        this.itemsLostOnDeath = combineSimilarItemStacks(deathItemLoss.getItemsLost());
    }
    
    @Nullable
    private static ItemStack[] combineSimilarItemStacks(@Nullable final ItemStack[] itemsLostOnDeath) {
        if (itemsLostOnDeath == null) {
            return null;
        }
        final ArrayList<ItemStack> singleItemStacks = new ArrayList<ItemStack>();
        final HashMap<String, ItemStack> combinedItemStacks = new HashMap<String, ItemStack>();
        for (final ItemStack itemStack : itemsLostOnDeath) {
            if (itemStack.getItem().getMaxStack() <= 1) {
                singleItemStacks.add(itemStack);
            }
            else {
                final String itemId = itemStack.getItemId();
                int quantity = itemStack.getQuantity();
                final ItemStack combinedItemStack = combinedItemStacks.get(itemId);
                if (combinedItemStack != null) {
                    quantity += combinedItemStack.getQuantity();
                }
                combinedItemStacks.put(itemId, itemStack.withQuantity(quantity));
            }
        }
        singleItemStacks.addAll(combinedItemStacks.values());
        return singleItemStacks.toArray(ItemStack[]::new);
    }
    
    @Override
    public void build(@Nonnull final Ref<EntityStore> ref, @Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder, @Nonnull final Store<EntityStore> store) {
        commandBuilder.append("Pages/RespawnPage.ui");
        commandBuilder.set("#DeathReason.TextSpans", (this.deathReason != null) ? this.deathReason : Message.empty());
        if (!this.displayDataOnDeathScreen) {
            commandBuilder.set("#DeathData.Visible", false);
        }
        else {
            final DecimalFormat decimalFormat = new DecimalFormat("#.##");
            decimalFormat.setDecimalSeparatorAlwaysShown(false);
            if (this.deathItemLoss.getLossMode() == DeathConfig.ItemsLossMode.NONE) {
                commandBuilder.set("#ItemsLossStatus.TextSpans", Message.translation("server.general.itemsLossPrevented"));
            }
            else {
                commandBuilder.set("#ItemsLossStatus.TextSpans", Message.translation("server.general.itemsDurabilityLoss").param("percentage", decimalFormat.format(this.deathItemLoss.getDurabilityLossPercentage())));
            }
            if (this.itemsLostOnDeath == null || this.itemsLostOnDeath.length == 0) {
                commandBuilder.set("#ItemsAmountLoss.Visible", false);
                commandBuilder.set("#DroppedItemsContainer.Visible", false);
            }
            else {
                commandBuilder.set("#ItemsAmountLoss.TextSpans", Message.translation("server.general.itemsAmountLoss"));
                commandBuilder.set("#DroppedItemsContainer.Visible", true);
                commandBuilder.clear("#DroppedItemsContainer");
                for (int i = 0; i < this.itemsLostOnDeath.length; ++i) {
                    final ItemStack itemStack = this.itemsLostOnDeath[i];
                    final String itemSelector = "#DroppedItemsContainer[" + i + "] ";
                    commandBuilder.append("#DroppedItemsContainer", "Pages/DroppedItemSlot.ui");
                    commandBuilder.set(itemSelector + "#ItemIcon.ItemId", itemStack.getItemId());
                    commandBuilder.set(itemSelector + "#ItemIcon.Quantity", itemStack.getQuantity());
                    if (itemStack.getQuantity() > 1) {
                        commandBuilder.set(itemSelector + "#QuantityLabel.Text", String.valueOf(itemStack.getQuantity()));
                    }
                    else {
                        commandBuilder.set(itemSelector + "#QuantityLabel.Visible", false);
                    }
                }
            }
        }
        eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#RespawnButton", EventData.of("Action", "Respawn"));
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final RespawnPageEventData data) {
        if (!"Respawn".equals(data.action)) {
            return;
        }
        final PlayerRef playerRef = store.getComponent(ref, PlayerRef.getComponentType());
        assert playerRef != null;
        final UICommandBuilder commandBuilder = new UICommandBuilder();
        commandBuilder.set("#RespawnButton.Disabled", true);
        this.sendUpdate(commandBuilder);
        CompletableFutureUtil._catch(DeathComponent.respawn(store, ref).thenCompose(v -> {
            final Ref<EntityStore> currentRef = playerRef.getReference();
            if (currentRef == null || !currentRef.isValid()) {
                return CompletableFuture.completedFuture((Object)null);
            }
            else {
                return (CompletableFuture<Object>)CompletableFuture.runAsync(() -> {
                    if (!(!currentRef.isValid())) {
                        final Player playerComponent = currentRef.getStore().getComponent(currentRef, Player.getComponentType());
                        if (!RespawnPage.$assertionsDisabled && playerComponent == null) {
                            throw new AssertionError();
                        }
                        else if (playerComponent.getPageManager().getCustomPage() == this) {
                            playerComponent.getPageManager().setPage(currentRef, currentRef.getStore(), Page.None);
                        }
                    }
                }, currentRef.getStore().getExternalData().getWorld());
            }
        }));
    }
    
    @Override
    public void onDismiss(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store) {
        super.onDismiss(ref, store);
        final boolean isDead = store.getArchetype(ref).contains(DeathComponent.getComponentType());
        if (isDead) {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            assert playerComponent != null;
            DeathComponent.respawn(store, ref);
        }
    }
    
    public static class RespawnPageEventData
    {
        static final String KEY_ACTION = "Action";
        static final String ACTION_RESPAWN = "Respawn";
        public static final BuilderCodec<RespawnPageEventData> CODEC;
        private String action;
        
        static {
            CODEC = BuilderCodec.builder(RespawnPageEventData.class, RespawnPageEventData::new).addField(new KeyedCodec<String>("Action", Codec.STRING), (entry, s) -> entry.action = s, entry -> entry.action).build();
        }
    }
}
