package com.tiedup.remake.network.minigame;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.minigame.ContinuousStruggleMiniGameState.UpdateType;
import com.tiedup.remake.network.base.AbstractClientPacket;
import java.util.UUID;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Server to Client packet for continuous struggle mini-game state updates.
 *
 * Sent when:
 * - START: Session begins (opens the GUI)
 * - DIRECTION_CHANGE: Direction changed
 * - RESISTANCE_UPDATE: Resistance reduced
 * - SHOCK: Shock collar triggered
 * - ESCAPE: Player escaped successfully
 * - END: Session ended (cancelled or completed)
 */
public class PacketContinuousStruggleState extends AbstractClientPacket {

    private final UUID sessionId;
    private final UpdateType updateType;
    private final int currentDirection;
    private final int currentResistance;
    private final int maxResistance;
    private final boolean isLocked;

    public PacketContinuousStruggleState(
        UUID sessionId,
        UpdateType updateType,
        int currentDirection,
        int currentResistance,
        int maxResistance,
        boolean isLocked
    ) {
        this.sessionId = sessionId;
        this.updateType = updateType;
        this.currentDirection = currentDirection;
        this.currentResistance = currentResistance;
        this.maxResistance = maxResistance;
        this.isLocked = isLocked;
    }

    public void encode(FriendlyByteBuf buf) {
        buf.writeUUID(sessionId);
        buf.writeVarInt(updateType.ordinal());
        buf.writeVarInt(currentDirection);
        buf.writeVarInt(currentResistance);
        buf.writeVarInt(maxResistance);
        buf.writeBoolean(isLocked);
    }

    public static PacketContinuousStruggleState decode(FriendlyByteBuf buf) {
        UUID sessionId = buf.readUUID();
        UpdateType updateType = UpdateType.values()[buf.readVarInt()];
        int currentDirection = buf.readVarInt();
        int currentResistance = buf.readVarInt();
        int maxResistance = buf.readVarInt();
        boolean isLocked = buf.readBoolean();
        return new PacketContinuousStruggleState(
            sessionId,
            updateType,
            currentDirection,
            currentResistance,
            maxResistance,
            isLocked
        );
    }

    @Override
    @OnlyIn(Dist.CLIENT)
    protected void handleClientImpl() {
        ClientHandler.handle(this);
    }

    @OnlyIn(Dist.CLIENT)
    private static class ClientHandler {

        private static void handle(PacketContinuousStruggleState pkt) {
            net.minecraft.client.Minecraft mc =
                net.minecraft.client.Minecraft.getInstance();
            if (mc.player == null) {
                TiedUpMod.LOGGER.warn(
                    "[PacketContinuousStruggleState] Player is null, cannot handle packet"
                );
                return;
            }

            TiedUpMod.LOGGER.info(
                "[PacketContinuousStruggleState] Received update: type={}, direction={}, resistance={}/{}",
                pkt.updateType,
                pkt.currentDirection,
                pkt.currentResistance,
                pkt.maxResistance
            );

            switch (pkt.updateType) {
                case START -> {
                    // Open the continuous struggle screen
                    TiedUpMod.LOGGER.info(
                        "[PacketContinuousStruggleState] Opening ContinuousStruggleMiniGameScreen"
                    );
                    mc.setScreen(
                        new com.tiedup.remake.client.gui.screens.ContinuousStruggleMiniGameScreen(
                            pkt.sessionId,
                            pkt.currentDirection,
                            pkt.currentResistance,
                            pkt.maxResistance,
                            pkt.isLocked
                        )
                    );
                }
                case DIRECTION_CHANGE -> {
                    if (
                        mc.screen instanceof
                            com.tiedup.remake.client.gui.screens.ContinuousStruggleMiniGameScreen screen
                    ) {
                        screen.onDirectionChange(pkt.currentDirection);
                    }
                }
                case RESISTANCE_UPDATE -> {
                    if (
                        mc.screen instanceof
                            com.tiedup.remake.client.gui.screens.ContinuousStruggleMiniGameScreen screen
                    ) {
                        screen.onResistanceUpdate(pkt.currentResistance);
                    }
                }
                case SHOCK -> {
                    if (
                        mc.screen instanceof
                            com.tiedup.remake.client.gui.screens.ContinuousStruggleMiniGameScreen screen
                    ) {
                        screen.onShock();
                    }
                }
                case ESCAPE -> {
                    if (
                        mc.screen instanceof
                            com.tiedup.remake.client.gui.screens.ContinuousStruggleMiniGameScreen screen
                    ) {
                        screen.onEscape();
                    }
                }
                case END -> {
                    if (
                        mc.screen instanceof
                            com.tiedup.remake.client.gui.screens.ContinuousStruggleMiniGameScreen screen
                    ) {
                        screen.onEnd();
                    }
                }
            }
        }
    }

    // Getters for potential external use
    public UUID getSessionId() {
        return sessionId;
    }

    public UpdateType getUpdateType() {
        return updateType;
    }

    public int getCurrentDirection() {
        return currentDirection;
    }

    public int getCurrentResistance() {
        return currentResistance;
    }

    public int getMaxResistance() {
        return maxResistance;
    }

    public boolean isLocked() {
        return isLocked;
    }
}
