import { world, system } from "@minecraft/server";

const SAPLING_BLOCK = "ods_orch:wild_cherry_tree_sapling";
const LOG = "ods_orch:wild_cherry_tree_log";
const LEAVES = "ods_orch:wild_cherry_tree_leaves";
const FLOWER = "ods_orch:wild_cherry_tree_fruit_side";

function rand(n) { return Math.floor(Math.random() * n); }
function chance(p) { return Math.random() < p; }

// Build a wisteria tree procedurally. Variant 0/1/2 = subtle canopy width tweaks.
// Roughly 25% larger than the prior 5-tall structures: 7-block trunk, 7x7 base canopy.
function buildWisteria(dim, x, y, z, variant) {
  const cmds = [];
  const trunkH = 6 + (variant === 1 ? 1 : 0); // 6 or 7
  const wide = variant === 2 ? 4 : 3;          // half-extent of widest canopy ring
  const mid = wide - 1;
  const narrow = mid - 1;

  // Clear sapling tile, then place trunk.
  cmds.push(`setblock ${x} ${y} ${z} air`);
  for (let dy = 0; dy < trunkH; dy++) {
    cmds.push(`setblock ${x} ${y + dy} ${z} ${LOG}`);
  }

  const canopyBase = y + trunkH - 2; // canopy starts 2 below the very top so the trunk pokes up
  // Wide ring (full square minus corners)
  fillSquareRing(cmds, x, canopyBase, z, wide, true);
  fillSquareRing(cmds, x, canopyBase + 1, z, wide, true);
  // Mid ring
  fillSquareRing(cmds, x, canopyBase + 2, z, mid, false);
  // Narrow cap
  fillSquareRing(cmds, x, canopyBase + 3, z, narrow, false);
  cmds.push(`setblock ${x} ${canopyBase + 4} ${z} ${LEAVES} [] replace air`);

  // Hanging wisteria flower tassels: drop FLOWER blocks 1-3 below the wide ring edges.
  const edgeOffsets = [
    [-wide, 0], [wide, 0], [0, -wide], [0, wide],
    [-mid, -mid], [-mid, mid], [mid, -mid], [mid, mid],
    [-wide, -1], [-wide, 1], [wide, -1], [wide, 1],
    [-1, -wide], [1, -wide], [-1, wide], [1, wide],
  ];
  for (const [dx, dz] of edgeOffsets) {
    if (!chance(0.7)) continue;
    const drop = 1 + rand(3); // 1-3 blocks
    for (let i = 1; i <= drop; i++) {
      cmds.push(`setblock ${x + dx} ${canopyBase - i} ${z + dz} ${FLOWER} [] replace air`);
    }
  }

  return cmds;
}

// Fill a hollow square (or solid) ring of LEAVES at level y with given half-extent r.
// `clipCorners` true = drop the four extreme corners for a softer outline.
function fillSquareRing(cmds, cx, cy, cz, r, clipCorners) {
  const x1 = cx - r, x2 = cx + r;
  const z1 = cz - r, z2 = cz + r;
  cmds.push(`fill ${x1} ${cy} ${z1} ${x2} ${cy} ${z2} ${LEAVES} replace air`);
  if (clipCorners) {
    cmds.push(`setblock ${x1} ${cy} ${z1} air`);
    cmds.push(`setblock ${x2} ${cy} ${z1} air`);
    cmds.push(`setblock ${x1} ${cy} ${z2} air`);
    cmds.push(`setblock ${x2} ${cy} ${z2} air`);
  }
}

function growSapling(block, player) {
  const dim = block.dimension;
  const { x, y, z } = block.location;
  const variant = rand(3);
  const cmds = buildWisteria(dim, x, y, z, variant);
  let i = 0;
  // Throttle to ~30 commands per tick to avoid command-rate spikes.
  const step = () => {
    const end = Math.min(i + 30, cmds.length);
    for (; i < end; i++) {
      try { dim.runCommand(cmds[i]); } catch (_) {}
    }
    if (i < cmds.length) system.runTimeout(step, 1);
    else if (player) player.sendMessage("§5[Trees] §7A wisteria blooms.");
  };
  step();
}

// Bonemeal usage on sapling → grow tree
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  const block = event.block;
  if (!block || block.typeId !== SAPLING_BLOCK) return;
  const stack = event.itemStack;
  if (!stack || stack.typeId !== "minecraft:bone_meal") return;
  event.cancel = true;
  const player = event.player;
  system.run(() => {
    growSapling(block, player);
    // Consume one bonemeal
    try {
      const inv = player.getComponent("minecraft:inventory")?.container;
      if (inv) {
        const sel = player.selectedSlotIndex;
        const cur = inv.getItem(sel);
        if (cur && cur.typeId === "minecraft:bone_meal") {
          if (cur.amount > 1) { cur.amount -= 1; inv.setItem(sel, cur); }
          else { inv.setItem(sel, undefined); }
        }
      }
    } catch (_) {}
  });
});

system.run(() => {
  world.sendMessage("§5[Trees] §7Wisteria pack loaded.");
});
