/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.fightsystem.utils;

import de.steamwar.fightsystem.Config;
import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.craftbukkit.block.data.CraftBlockData;

import java.util.List;

public class HullHiderWrapper {
    public static final HullHiderWrapper impl = new HullHiderWrapper();

    public Object generateBlockChangePacket(List<Hull.IntVector> changes) {
        Object[] blockdata = new Object[changes.size()];
        for (int i = 0; i < blockdata.length; i++) {
            Hull.IntVector change = changes.get(i);
            blockdata[i] = ((CraftBlockData) Config.world.getBlockData(change.getX(), change.getY(), change.getZ())).getState();
        }

        return generateBlockChangePacket(changes, blockdata);
    }

    private Object generateBlockChangePacket(List<Hull.IntVector> changes, Object[] blockdata) {
        if (changes.size() > 1) {
            Hull.IntVector section = changes.get(0);
            section = new Hull.IntVector(section.getX() >> 4, section.getY() >> 4, section.getZ() >> 4);
            int xOffset = 16 * section.getX();
            int yOffset = 16 * section.getY();
            int zOffset = 16 * section.getZ();

            short[] pos = new short[changes.size()];
            for (int i = 0; i < changes.size(); i++) {
                Hull.IntVector change = changes.get(i);

                pos[i] = (short) (((change.getX() - xOffset) << 8) + ((change.getZ() - zOffset) << 4) + (change.getY() - yOffset));
            }

            return constructMultiBlockChange(section, pos, blockdata);
        } else {
            Hull.IntVector pos = changes.get(0);
            return new ClientboundBlockUpdatePacket(new BlockPos(pos.getX(), pos.getY(), pos.getZ()), (BlockState) blockdata[0]);
        }
    }

    protected Object constructMultiBlockChange(Hull.IntVector section, short[] pos, Object[] blockdata) {
        return new ClientboundSectionBlocksUpdatePacket(SectionPos.of(section.getX(), section.getY(), section.getZ()), new Short2ObjectArrayMap<>(pos, blockdata, blockdata.length));
    }
}
