package com.firefrostgaming.bitchbot;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.CommandBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;

import java.util.List;

/**
 * Places impulse command blocks at each position from provision.json with
 * "/tp @p originalSpawn.x originalSpawn.y originalSpawn.z" baked in.
 *
 * Uses CommandBlockEntity directly rather than spawning items / triggering
 * events. The command-block GUI normally requires op + cheats enabled to
 * write to NBT, but server-side code goes underneath that gate.
 *
 * Block facing comes from provision.json. We use BlockStateProperties.FACING
 * which command blocks support natively.
 */
public class CommandBlockPlacer {

    public static void placeAll(ServerLevel level,
                                List<ProvisionConfig.CommandBlockEntry> entries,
                                BlockPos originalSpawn) {
        if (entries == null || entries.isEmpty()) {
            BitchBot.LOGGER.info("[BitchBot] No command blocks specified — skipping.");
            return;
        }

        String tpCommand = String.format("tp @p %d %d %d",
                originalSpawn.getX(), originalSpawn.getY(), originalSpawn.getZ());

        int placed = 0;
        for (ProvisionConfig.CommandBlockEntry entry : entries) {
            try {
                BlockPos pos = new BlockPos(entry.position.x, entry.position.y, entry.position.z);
                Direction facing = parseFacing(entry.facing);

                BlockState state = Blocks.COMMAND_BLOCK.defaultBlockState();
                if (state.hasProperty(BlockStateProperties.FACING)) {
                    state = state.setValue(BlockStateProperties.FACING, facing);
                }
                level.setBlock(pos, state, 2);

                BlockEntity be = level.getBlockEntity(pos);
                if (be instanceof CommandBlockEntity cbe) {
                    cbe.getCommandBlock().setCommand(tpCommand);
                    cbe.setChanged();
                    placed++;
                } else {
                    BitchBot.LOGGER.warn("[BitchBot] Command block at {} has no BlockEntity after setBlock — skipped.", pos);
                }
            } catch (Throwable t) {
                BitchBot.LOGGER.error("[BitchBot] Failed to place command block: {}", t.getMessage());
            }
        }
        BitchBot.LOGGER.info("[BitchBot] Command blocks placed: {} / {}", placed, entries.size());
    }

    private static Direction parseFacing(String s) {
        if (s == null) return Direction.UP;
        switch (s.toLowerCase()) {
            case "down":  return Direction.DOWN;
            case "north": return Direction.NORTH;
            case "south": return Direction.SOUTH;
            case "east":  return Direction.EAST;
            case "west":  return Direction.WEST;
            case "up":
            default:      return Direction.UP;
        }
    }
}
