import { BlockPermutation, BlockVolume, Entity, EntityHitEntityAfterEvent, ItemStack, system, world } from '@minecraft/server';
import { Vec3 } from '../utils/Vec3';
class Bear {
  static BEAR_ENTITY_TYPES = [
    'sf_nba:black_bear',
    'sf_nba:grizzly_bear'
  ]
  static BEAR_FOOD_BLOCK_FILTERS = {
    includePermutations: [
      BlockPermutation.resolve('minecraft:sweet_berry_bush', { growth: 2 }),
      BlockPermutation.resolve('minecraft:sweet_berry_bush', { growth: 3 }),
      BlockPermutation.resolve('minecraft:sweet_berry_bush', { growth: 4 }),
      BlockPermutation.resolve('minecraft:sweet_berry_bush', { growth: 5 }),
      BlockPermutation.resolve('minecraft:sweet_berry_bush', { growth: 6 }),
      BlockPermutation.resolve('minecraft:sweet_berry_bush', { growth: 7 }),
      BlockPermutation.resolve('minecraft:beehive', { honey_level: 5 }),
      BlockPermutation.resolve('minecraft:bee_nest', { honey_level: 5 })
    ]
  }
  static BEAR_HARVEST_PATHFINDER_TYPE = 'sf_nba:bear_harvest_pathfinder';
  static BEAR_EATING_PARTICLES = [
    'sf_nba:bear_eating_honeycomb',
    'sf_nba:bear_eating_sweet_berries',
    'sf_nba:bear_eating_salmon',
    'sf_nba:bear_eating_cooked_salmon',
    'sf_nba:bear_eating_venison'
  ]
  constructor() {
    this.bearHitHandler = this.bearHitHandler.bind(this);
    this.initGoals();
  }
  initGoals() {
    world.afterEvents.entityHitEntity.subscribe(this.bearHitHandler, { entityTypes: Bear.BEAR_ENTITY_TYPES });
    world.afterEvents.dataDrivenEntityTrigger.subscribe(event => {
      const { entity: bear, eventId } = event;
      if (eventId === 'sf_nba:configure_eating') {
        this.eating(bear);
        return;
      }
      this.searchForFood(bear, 8, 3);
    }, {
      entityTypes: Bear.BEAR_ENTITY_TYPES,
      eventTypes: [
        'sf_nba:configure_eating',
        'sf_nba:harvest_sensor'
      ]
    });
  }
  eating(bear) {
    const { dimension } = bear;
    const foodParticle = Bear.BEAR_EATING_PARTICLES[bear.getProperty('sf_nba:holding_food') - 1];
    let eatCounter = 0;
    const handleEating = system.runInterval(() => {
      const isValid = bear.isValid();
      const location = isValid ? bear.location : undefined;
      if (!isValid || !(bear.getProperty('sf_nba:is_sitting') && bear.getProperty('sf_nba:holding_food'))) {
        system.clearRun(handleEating);
        if (!isValid) return;
        bear.triggerEvent('sf_nba:configure_holding_food_no_sitting');
        return;
      }
      if (eatCounter % 5 == 0 || eatCounter == 0) {
        const snoutVec = new Vec3(0.07, 0.65, 1.21).rotateY(bear.getRotation().y).add(location);
        try { dimension.spawnParticle(foodParticle, snoutVec) } catch {};
      }
      if (eatCounter > 40) {
        bear.runCommand('replaceitem entity @s slot.weapon.mainhand 0 air');
        system.run(() => bear.triggerEvent('sf_nba:on_eat'));
        system.clearRun(handleEating);
        return;
      }
      eatCounter++;
    });
  }
  searchForFood(bear, range, verticalRange) {
    const { dimension, location } = bear;
    const fromLoc = new Vec3(location.x - range, location.y - verticalRange, location.z - range);
    const toLoc = new Vec3(location.x + range, location.y + verticalRange, location.z + range);
    const blockVolumeList = dimension.getBlocks(new BlockVolume(fromLoc, toLoc), Bear.BEAR_FOOD_BLOCK_FILTERS, true);
    const blockLocIterator = blockVolumeList.getBlockLocationIterator();
    let result = blockLocIterator.next();
    if (result.done) return;
    bear.triggerEvent('sf_nba:move_to_harvest');
    const { BEAR_HARVEST_PATHFINDER_TYPE } = Bear;
    const blockLocation = result.value;
    if (dimension.getEntitiesAtBlockLocation(blockLocation).some(e => e.typeId === BEAR_HARVEST_PATHFINDER_TYPE)) return;
    blockLocation.x += 0.5;
    blockLocation.z += 0.5;
    dimension.spawnEntity(BEAR_HARVEST_PATHFINDER_TYPE, blockLocation);
  }
  bearHitHandler(eventData) {
    const { damagingEntity: bear, hitEntity: harvest } = eventData;
    if (harvest?.typeId !== Bear.BEAR_HARVEST_PATHFINDER_TYPE) return;
    const { dimension } = bear;
    const harvestBlock = dimension.getBlock(harvest.location);
    if (!harvestBlock?.isValid()) return;
    harvest.remove();
    const { typeId: harvestType, permutation } = harvestBlock;
    if (harvestType === 'minecraft:sweet_berry_bush') {
      const age = permutation.getState('growth');
      if (age < 2) return;
      const berryAmount = 1 + Math.floor(Math.random() * 2) + (age >= 3);
      harvestBlock.setPermutation(permutation.withState('growth', 1));
      dimension.spawnItem(new ItemStack('minecraft:sweet_berries', berryAmount), harvestBlock.center());
      dimension.playSound('block.sweet_berry_bush.pick', bear.location);
      return;
    }
    if (harvestType === 'minecraft:beehive' || harvestType === 'minecraft:bee_nest') {
      if (permutation.getState('honey_level') < 5) return;
      harvestBlock.setPermutation(permutation.withState('honey_level', 0));
      dimension.spawnItem(new ItemStack('minecraft:honeycomb', 3), harvestBlock.center());
      dimension.playSound('block.beehive.shear', bear.location);
    }
  }
}
new Bear();