package com.tiedup.remake.network.cell;

import com.tiedup.remake.blocks.entity.CellCoreBlockEntity;
import com.tiedup.remake.cells.*;
import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.network.PacketRateLimiter;
import java.util.function.Supplier;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.network.NetworkEvent;

/**
 * Client → Server packet: handles Cell Core menu button actions.
 */
public class PacketCoreMenuAction {

    public enum Action {
        SET_SPAWN,
        SET_DELIVERY,
        SET_DISGUISE,
        RESCAN,
    }

    private final BlockPos corePos;
    private final Action action;

    public PacketCoreMenuAction(BlockPos corePos, Action action) {
        this.corePos = corePos;
        this.action = action;
    }

    public static void encode(PacketCoreMenuAction msg, FriendlyByteBuf buf) {
        buf.writeBlockPos(msg.corePos);
        buf.writeEnum(msg.action);
    }

    public static PacketCoreMenuAction decode(FriendlyByteBuf buf) {
        return new PacketCoreMenuAction(
            buf.readBlockPos(),
            buf.readEnum(Action.class)
        );
    }

    public static void handle(
        PacketCoreMenuAction msg,
        Supplier<NetworkEvent.Context> ctx
    ) {
        ctx
            .get()
            .enqueueWork(() -> {
                ServerPlayer sender = ctx.get().getSender();
                if (sender == null) return;

                if (!PacketRateLimiter.allowPacket(sender, "core_menu")) {
                    return;
                }

                ServerLevel level = sender.serverLevel();
                BlockEntity be = level.getBlockEntity(msg.corePos);
                if (
                    !(be instanceof CellCoreBlockEntity core) ||
                    core.getCellId() == null
                ) {
                    return;
                }

                CellRegistryV2 registry = CellRegistryV2.get(level);
                CellDataV2 cell = registry.getCell(core.getCellId());
                if (cell == null) return;

                // Verify ownership
                if (
                    !cell.canPlayerManage(
                        sender.getUUID(),
                        sender.hasPermissions(2)
                    )
                ) {
                    sender.displayClientMessage(
                        Component.translatable(
                            "msg.tiedup.cell_core.not_owner"
                        ),
                        true
                    );
                    return;
                }

                switch (msg.action) {
                    case SET_SPAWN -> {
                        CellSelectionManager.startSelection(
                            sender.getUUID(),
                            SelectionMode.SET_SPAWN,
                            msg.corePos,
                            cell.getId(),
                            sender.blockPosition()
                        );
                        sender.displayClientMessage(
                            Component.translatable(
                                "msg.tiedup.cell_core.selection.spawn"
                            ).withStyle(ChatFormatting.YELLOW),
                            true
                        );
                    }
                    case SET_DELIVERY -> {
                        CellSelectionManager.startSelection(
                            sender.getUUID(),
                            SelectionMode.SET_DELIVERY,
                            msg.corePos,
                            cell.getId(),
                            sender.blockPosition()
                        );
                        sender.displayClientMessage(
                            Component.translatable(
                                "msg.tiedup.cell_core.selection.delivery"
                            ).withStyle(ChatFormatting.YELLOW),
                            true
                        );
                    }
                    case SET_DISGUISE -> {
                        CellSelectionManager.startSelection(
                            sender.getUUID(),
                            SelectionMode.SET_DISGUISE,
                            msg.corePos,
                            cell.getId(),
                            sender.blockPosition()
                        );
                        sender.displayClientMessage(
                            Component.translatable(
                                "msg.tiedup.cell_core.selection.disguise"
                            ).withStyle(ChatFormatting.YELLOW),
                            true
                        );
                    }
                    case RESCAN -> handleRescan(
                        sender,
                        registry,
                        cell,
                        core,
                        level,
                        msg.corePos
                    );
                }
            });

        ctx.get().setPacketHandled(true);
    }

    private static void handleRescan(
        ServerPlayer sender,
        CellRegistryV2 registry,
        CellDataV2 cell,
        CellCoreBlockEntity core,
        ServerLevel level,
        BlockPos corePos
    ) {
        FloodFillResult result = FloodFillAlgorithm.tryFill(level, corePos);

        if (result.isSuccess()) {
            registry.rescanCell(cell.getId(), result);

            // Sync spawn/delivery from Core BE to CellDataV2
            if (core.getSpawnPoint() != null) {
                cell.setSpawnPoint(core.getSpawnPoint());
            }
            if (core.getDeliveryPoint() != null) {
                cell.setDeliveryPoint(core.getDeliveryPoint());
            }

            sender.displayClientMessage(
                Component.translatable(
                    "msg.tiedup.cell_core.rescan_success",
                    result.getInterior().size(),
                    result.getWalls().size()
                ).withStyle(ChatFormatting.GREEN),
                true
            );

            TiedUpMod.LOGGER.info(
                "[PacketCoreMenuAction] {} rescanned cell {} ({} interior, {} walls)",
                sender.getName().getString(),
                cell.getId().toString().substring(0, 8),
                result.getInterior().size(),
                result.getWalls().size()
            );
        } else {
            sender.displayClientMessage(
                Component.translatable(
                    "msg.tiedup.cell_core.rescan_fail",
                    Component.translatable(result.getErrorKey())
                ).withStyle(ChatFormatting.RED),
                true
            );
        }
    }
}
