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

package com.hypixel.hytale.builtin.portals.ui;

import com.hypixel.hytale.codec.builder.BuilderCodec;
import java.util.UUID;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.builtin.portals.components.PortalDevice;
import java.util.Iterator;
import java.util.Collection;
import com.hypixel.hytale.server.core.asset.type.portalworld.PortalType;
import com.hypixel.hytale.builtin.portals.resources.PortalWorld;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.component.ComponentAccessor;
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.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.component.Ref;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.portals.components.PortalDeviceConfig;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;

public class PortalDeviceActivePage extends InteractiveCustomUIPage<Data>
{
    @Nonnull
    private final PortalDeviceConfig config;
    @Nonnull
    private final Ref<ChunkStore> blockRef;
    
    public PortalDeviceActivePage(@Nonnull final PlayerRef playerRef, @Nonnull final PortalDeviceConfig config, @Nonnull final Ref<ChunkStore> blockRef) {
        super(playerRef, CustomPageLifetime.CanDismissOrCloseThroughInteraction, Data.CODEC);
        this.config = config;
        this.blockRef = blockRef;
    }
    
    @Override
    public void build(@Nonnull final Ref<EntityStore> ref, @Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder, @Nonnull final Store<EntityStore> store) {
        final State state = this.computeState(ref, store);
        if (state == Error.INVALID_BLOCK) {
            return;
        }
        commandBuilder.append("Pages/PortalDeviceActive.ui");
        while (true) {
            if (state instanceof PortalIsOpen) {
                final PortalIsOpen portalIsOpen2;
                final PortalIsOpen portalIsOpen = portalIsOpen2 = (PortalIsOpen)state;
                try {
                    final World world = portalIsOpen2.world();
                    final PortalWorld portalWorld = portalIsOpen.portalWorld();
                    final boolean diedInside = portalIsOpen.diedInside();
                    if (!true) {
                        commandBuilder.set("#Error.Visible", true);
                        commandBuilder.set("#ErrorLabel.Text", Message.translation("server.customUI.portalDevice.unknownError").param("state", state.toString()));
                        return;
                    }
                    final boolean diedInIt = diedInside;
                    final PortalType portalType = portalWorld.getPortalType();
                    commandBuilder.set("#PortalPanel.Visible", true);
                    if (diedInIt) {
                        commandBuilder.set("#Died.Visible", true);
                    }
                    commandBuilder.set("#PortalTitle.TextSpans", Message.translation("server.customUI.portalDevice.portalTitle").param("name", portalType.getDisplayName()));
                    commandBuilder.set("#PortalDescription.TextSpans", PortalDeviceSummonPage.createDescription(portalType, portalWorld.getTimeLimitSeconds()));
                    final Message playerCountMsg = createPlayerCountMsg(world);
                    commandBuilder.set("#PlayersInside.TextSpans", playerCountMsg);
                    final double remainingSeconds = portalWorld.getRemainingSeconds(world);
                    if (remainingSeconds < portalWorld.getTimeLimitSeconds()) {
                        final int remainingMinutes = (int)Math.round(remainingSeconds / 60.0);
                        final Message remainingTimeMsg = (remainingMinutes <= 1) ? Message.translation("server.customUI.portalDevice.lessThanAMinute") : Message.translation("server.customUI.portalDevice.remainingMinutes").param("time", remainingMinutes);
                        commandBuilder.set("#RemainingDuration.TextSpans", Message.translation("server.customUI.portalDevice.remainingDuration").param("remaining", remainingTimeMsg.color("#ea4fa46b")));
                    }
                    else {
                        commandBuilder.set("#PortalIsOpen.Visible", true);
                        commandBuilder.set("#RemainingDuration.TextSpans", Message.translation("server.customUI.portalDevice.beTheFirst").color("#ea4fa46b"));
                    }
                }
                catch (final Throwable cause) {
                    throw new MatchException(cause.toString(), cause);
                }
                return;
            }
            continue;
        }
    }
    
    private static Message createPlayerCountMsg(final World world) {
        final int playerCount = world.getPlayerCount();
        final String pinkEnoughColor = "#ea4fa46b";
        if (playerCount == 0) {
            return Message.translation("server.customUI.portalDevice.playersInside").param("count", Message.translation("server.customUI.portalDevice.playersInsideNone").color(pinkEnoughColor));
        }
        if (playerCount <= 4) {
            final Message msg = Message.translation("server.customUI.portalDevice.playersInside").param("count", Message.raw("" + playerCount).color(pinkEnoughColor));
            final Collection<PlayerRef> playerRefs = world.getPlayerRefs();
            for (final PlayerRef ref : playerRefs) {
                msg.insert(Message.raw("- ").color("#6b6b6b6b")).insert(ref.getUsername());
            }
            return msg;
        }
        return Message.translation("server.customUI.portalDevice.playersInside").param("count", Message.raw("" + playerCount).color(pinkEnoughColor));
    }
    
    private State computeState(final Ref<EntityStore> ref, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (!this.blockRef.isValid()) {
            return Error.INVALID_BLOCK;
        }
        final Store<ChunkStore> chunkStore = this.blockRef.getStore();
        final PortalDevice portalDevice = chunkStore.getComponent(this.blockRef, PortalDevice.getComponentType());
        if (portalDevice == null) {
            return Error.INVALID_BLOCK;
        }
        final World destinationWorld = portalDevice.getDestinationWorld();
        if (destinationWorld == null) {
            return Error.INVALID_WORLD;
        }
        final Store<EntityStore> destinationStore = destinationWorld.getEntityStore().getStore();
        final PortalWorld portalWorld = destinationStore.getResource(PortalWorld.getResourceType());
        if (!portalWorld.exists()) {
            return Error.DESTINATION_NOT_FRAGMENT;
        }
        final UUIDComponent uuidComponent = componentAccessor.getComponent(ref, UUIDComponent.getComponentType());
        assert uuidComponent != null;
        final UUID playerUUID = uuidComponent.getUuid();
        final boolean diedInside = portalWorld.getDiedInWorld().contains(playerUUID);
        return new PortalIsOpen(destinationWorld, portalWorld, diedInside);
    }
    
    record PortalIsOpen(World world, PortalWorld portalWorld, boolean diedInside) implements State {}
    
    private enum Error implements State
    {
        INVALID_BLOCK, 
        INVALID_WORLD, 
        DESTINATION_NOT_FRAGMENT, 
        INACTIVE_PORTAL;
    }
    
    protected static class Data
    {
        public static final BuilderCodec<Data> CODEC;
        
        static {
            CODEC = BuilderCodec.builder(Data.class, Data::new).build();
        }
    }
    
    private sealed interface State permits PortalIsOpen, Error
    {
    }
}
