import { system, world, BlockPermutation, Direction } from '@minecraft/server';
import { decrementStack, getOppositeDirection, DirectionType, cardinalSides, randomFunction, shouldConnect } from './utils/helper';
import { directionToVector3 } from './utils/math';

system.beforeEvents.startup.subscribe(initEvent => {
  initEvent.blockComponentRegistry.registerCustomComponent('steve_bygone_slab:trigger', {
  beforeOnPlayerPlace: e => { const { x, y, z } = e.block.location;
let playerEquipment = e.player.getComponent('equippable').getEquipment('Mainhand');
if (playerEquipment === undefined) return;

let face = getOppositeDirection(e.face);
let blockToCheck = e.block.offset(directionToVector3(face));

const blockStateDouble = 'pa:is_double';
const blockStateHalf = 'minecraft:vertical_half';

if (blockToCheck.permutation.getState(blockStateDouble)) return;
if (blockToCheck.typeId !== playerEquipment.typeId) return;

if (face === 'Up' || face === 'Down') {
  const state = blockToCheck.permutation.getState(blockStateHalf);
  if ((face === 'Up' && state === 'top') || (face === 'Down' && state === 'bottom')) {
    e.cancel = true;

    system.run(() => {
      blockToCheck.dimension.playSound("use.stone", blockToCheck.location, { pitch: 0.8, volume: 1.0 });

      blockToCheck.setPermutation(BlockPermutation.resolve(blockToCheck.typeId, { [blockStateDouble]: true }));

      decrementStack(e.player);
    });
  }
}
 },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_colorless_spawner:trigger', {
  onTick: e => { const { x, y, z } = e.block.location;
e.dimension.runCommand(`execute positioned ${x} ${y} ${z} run function colorlesssplacer`); },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_bygone_stairs:trigger', {
  onPlace: e => { const { x, y, z } = e.block.location;
e.dimension.playSound("normal", e.block.location, { pitch: 0.8, volume: 1.0 }); },
beforeOnPlayerPlace: e => { const { x, y, z } = e.block.location;
let face = e.permutationToPlace.getState('minecraft:cardinal_direction');
let half = e.permutationToPlace.getState('minecraft:vertical_half');
let blockPermutation = e.permutationToPlace;
let blockToCheck;

switch (face) {
  case 'north':
    {
      for (const direction of DirectionType.HORIZONTAL) {
        blockToCheck = e.block.offset(directionToVector3(direction));
        if (blockToCheck.typeId !== blockPermutation.type.id) continue;

        const blockToCheckHalf = blockToCheck.permutation.getState('minecraft:vertical_half');
        if (blockToCheckHalf !== half) continue;

        const blockToCheckDirection = blockToCheck.permutation.getState('minecraft:cardinal_direction');

        switch (direction) {
          case Direction.North:
            if (blockToCheckDirection === 'west') blockPermutation = blockPermutation.withState('pa:shape', 'outer_left');
            if (blockToCheckDirection === 'east') blockPermutation = blockPermutation.withState('pa:shape', 'outer_right');
            break;
          case Direction.South:
            if (blockToCheckDirection === 'east') blockPermutation = blockPermutation.withState('pa:shape', 'inner_left');
            if (blockToCheckDirection === 'west') blockPermutation = blockPermutation.withState('pa:shape', 'inner_right');
            break;
          case Direction.East:
            if (blockToCheckDirection === 'east') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_right'));
            if (blockToCheckDirection === 'west') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_right'));
            break;
          case Direction.West:
            if (blockToCheckDirection === 'west') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_left'));
            if (blockToCheckDirection === 'east') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_left'));
            break;
          default:
            break;
        }
      }
    }
    break;
  case 'south':
    {
      blockPermutation = blockPermutation.withState('pa:south', true);
      for (const direction of DirectionType.HORIZONTAL) {
        blockToCheck = e.block.offset(directionToVector3(direction));
        if (blockToCheck.typeId !== blockPermutation.type.id) continue;

        const blockToCheckHalf = blockToCheck.permutation.getState('minecraft:vertical_half');
        if (blockToCheckHalf !== half) continue;

        const blockToCheckDirection = blockToCheck.permutation.getState('minecraft:cardinal_direction');

        switch (direction) {
          case Direction.North:
            if (blockToCheckDirection === 'west') blockPermutation = blockPermutation.withState('pa:shape', 'inner_left');
            if (blockToCheckDirection === 'east') blockPermutation = blockPermutation.withState('pa:shape', 'inner_right');
            break;
          case Direction.South:
            if (blockToCheckDirection === 'east') blockPermutation = blockPermutation.withState('pa:shape', 'outer_left');
            if (blockToCheckDirection === 'west') blockPermutation = blockPermutation.withState('pa:shape', 'outer_right');
            break;
          case Direction.East:
            if (blockToCheckDirection === 'east') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_left'));
            if (blockToCheckDirection === 'west') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_left'));
            break;
          case Direction.West:
            if (blockToCheckDirection === 'west') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_right'));
            if (blockToCheckDirection === 'east') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_right'));
            break;
          default:
            break;
        }
      }
    }
    break;
  case 'east':
    {
      for (const direction of DirectionType.HORIZONTAL) {
        blockToCheck = e.block.offset(directionToVector3(direction));
        if (blockToCheck.typeId !== blockPermutation.type.id) continue;

        const blockToCheckHalf = blockToCheck.permutation.getState('minecraft:vertical_half');
        if (blockToCheckHalf !== half) continue;

        const blockToCheckDirection = blockToCheck.permutation.getState('minecraft:cardinal_direction');

        switch (direction) {
          case Direction.East:
            if (blockToCheckDirection === 'north') blockPermutation = blockPermutation.withState('pa:shape', 'outer_left');
            if (blockToCheckDirection === 'south') blockPermutation = blockPermutation.withState('pa:shape', 'outer_right');
            break;
          case Direction.West:
            if (blockToCheckDirection === 'south') blockPermutation = blockPermutation.withState('pa:shape', 'inner_left');
            if (blockToCheckDirection === 'north') blockPermutation = blockPermutation.withState('pa:shape', 'inner_right');
            break;
          case Direction.North:
            if (blockToCheckDirection === 'north') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_left'));
            if (blockToCheckDirection === 'south') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_left'));
            break;
          case Direction.South:
            if (blockToCheckDirection === 'north') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_right'));
            if (blockToCheckDirection === 'south') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_right'));
            break;
          default:
            break;
        }
      }
    }
    break;
  case 'west':
    {
      for (const direction of DirectionType.HORIZONTAL) {
        blockToCheck = e.block.offset(directionToVector3(direction));
        if (blockToCheck.typeId !== blockPermutation.type.id) continue;

        const blockToCheckHalf = blockToCheck.permutation.getState('minecraft:vertical_half');
        if (blockToCheckHalf !== half) continue;

        const blockToCheckDirection = blockToCheck.permutation.getState('minecraft:cardinal_direction');

        switch (direction) {
          case Direction.East:
            if (blockToCheckDirection === 'north') blockPermutation = blockPermutation.withState('pa:shape', 'inner_left');
            if (blockToCheckDirection === 'south') blockPermutation = blockPermutation.withState('pa:shape', 'inner_right');
            break;
          case Direction.West:
            if (blockToCheckDirection === 'south') blockPermutation = blockPermutation.withState('pa:shape', 'outer_left');
            if (blockToCheckDirection === 'north') blockPermutation = blockPermutation.withState('pa:shape', 'outer_right');
            break;
          case Direction.North:
            if (blockToCheckDirection === 'north') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_right'));
            if (blockToCheckDirection === 'south') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_right'));
            break;
          case Direction.South:
            if (blockToCheckDirection === 'north') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'outer_left'));
            if (blockToCheckDirection === 'south') blockToCheck.setPermutation(blockToCheck.permutation.withState('pa:shape', 'inner_left'));
            break;
          default:
            break;
        }
      }
    }
    break;
  default:
    break;
}
e.permutationToPlace = blockPermutation;
 },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_dark_spawner:trigger', {
  onTick: e => { const { x, y, z } = e.block.location;
e.dimension.runCommand(`execute positioned ${x} ${y} ${z} run function darkplacer`); },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_darksteve_spawner:trigger', {
  onTick: e => { const { x, y, z } = e.block.location;
e.dimension.runCommand(`execute positioned ${x} ${y} ${z} run function darksteveplacer`); },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_reverse_spawner:trigger', {
  onTick: e => { const { x, y, z } = e.block.location;
e.dimension.runCommand(`execute positioned ${x} ${y} ${z} run function reverseplacer`); },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_shadow_sapling:trigger', {
  onRandomTick: e => { const { x, y, z } = e.block.location;
const { block, dimension } = e;

block.setType('minecraft:air');
dimension.placeFeature("steve:dark_tree", block.location);
 },
onPlayerInteract: e => { const { x, y, z } = e.block.location;
const { block, dimension, player } = e;

if (!player) return;

const equippable = player.getComponent("minecraft:equippable");
if (!equippable) return;

const mainhand = equippable.getEquipmentSlot("Mainhand");
if (!mainhand.hasItem() || mainhand.typeId !== "minecraft:bone_meal")
    return;

if (mainhand.amount > 1) mainhand.amount--;
else mainhand.setItem(undefined);

block.setType('minecraft:air');
dimension.placeFeature("steve:dark_tree", block.location);

const effectLocation = block.center();
dimension.playSound("item.bone_meal.use", effectLocation);
dimension.spawnParticle(
    "minecraft:crop_growth_emitter",
    effectLocation
);
 },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_sun_spawner:trigger', {
  onTick: e => { const { x, y, z } = e.block.location;
e.dimension.runCommand(`execute positioned ${x} ${y} ${z} run function sunguardplacer`); },
});

initEvent.blockComponentRegistry.registerCustomComponent('steve_violet_sapling:trigger', {
  onRandomTick: e => { const { x, y, z } = e.block.location;
const { block, dimension } = e;

block.setType('minecraft:air');
dimension.placeFeature("steve:violet_tree1", block.location);
 },
onPlayerInteract: e => { const { x, y, z } = e.block.location;
const { block, dimension, player } = e;

if (!player) return;

const equippable = player.getComponent("minecraft:equippable");
if (!equippable) return;

const mainhand = equippable.getEquipmentSlot("Mainhand");
if (!mainhand.hasItem() || mainhand.typeId !== "minecraft:bone_meal")
    return;

if (mainhand.amount > 1) mainhand.amount--;
else mainhand.setItem(undefined);

block.setType('minecraft:air');
dimension.placeFeature("steve:violet_tree1", block.location);

const effectLocation = block.center();
dimension.playSound("item.bone_meal.use", effectLocation);
dimension.spawnParticle(
    "minecraft:crop_growth_emitter",
    effectLocation
);
 },
});

});
