import { BlockInventoryComponent, Container, system, world } from '@minecraft/server';
import { Helper } from '../utils/Helper';
import { NotSearchableByRaccoon } from '../item/NotSearchableByRaccoon';
export class Raccoon {
  static IDENTIFIER = 'sf_nba:raccoon';
  static VALID_CONTAINERS = ['minecraft:chest', 'minecraft:trapped_chest', 'minecraft:barrel'];
  static SEARCHING_ITEM_EVENT = 'sf_nba:raccoon_searching_item';
  static CANCEL_SEARCHING_ITEM_EVENT = 'sf_nba:raccoon_cancel_searching_item';
  static HOLDING_ITEM_EVENT = 'sf_nba:raccoon_holding_item';
  static SEARCH_CONTAINER_DELAY_EVENT = 'sf_nba:raccoon_search_container_delay';
  static TRIGGERED_CONTAINERS = [];
  constructor() {
    this.onSearchingItemOnChest();
    this.onCancelSearchingItemOnChest();
    this.removeTriggeredContainer();
  }
  onSearchingItemOnChest() {
    system.afterEvents.scriptEventReceive.subscribe((e) => {
      try {
        const entity = e.sourceEntity;
        if (entity == null) return;
        if (entity.typeId === undefined) return;
        if (entity.typeId !== Raccoon.IDENTIFIER) return;
        if (e.id !== Raccoon.SEARCHING_ITEM_EVENT) return;
        const containerBlock = entity.getBlockFromViewDirection({
          includeLiquidBlocks: false,
          includePassableBlocks: false,
        })?.block;
        if (containerBlock == null) {
          entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
          return;
        }
        if (!this.isValidContainer(containerBlock)) {
          entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
          return;
        }
        const isBeingSearched = Raccoon.TRIGGERED_CONTAINERS.some(container => 
          Helper.compareVector3(container.block.location, containerBlock.location)
        );
        if (isBeingSearched) {
          entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
          return;
        }
        Raccoon.TRIGGERED_CONTAINERS.push({
          block: containerBlock,
          entity: entity
        });
        entity.setProperty('sf_nba:container_type', this.getTriggeredContainerIdentifier(containerBlock));
        const inventory = containerBlock.getComponent(BlockInventoryComponent.componentId).container;
        const itemsCount = inventory.size - inventory.emptySlotsCount;
        const items = [];
        const [min, max] = [3.0, 9.0];
        const waitTime = Math.floor(Math.random() * (max - min + 1)) + min;
        system.runTimeout(() => {
          try {
            if (!entity.isValid()) {
              this.removeTriggeredContainer(containerBlock);
              return;
            }
            if (entity.getProperty('sf_nba:search_state') !== 'searching_item') {
              this.removeTriggeredContainer(containerBlock);
              return;
            }
            if (itemsCount === 0) {
              entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
              this.removeTriggeredContainer(containerBlock);
              return;
            }
            for (let i = 0; i < inventory.size; i++) {
              const item = inventory.getItem(i);
              if (!item) continue;
              if (!Helper.isItemOrBlockItem(item) || NotSearchableByRaccoon.includes(item.typeId)) continue;
              items.push({
                slot: i,
                identifier: item.typeId,
                stack: item.clone(),
              });
            }
            if (items.length === 0) {
              entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
              this.removeTriggeredContainer(containerBlock);
              return;
            }
            const slot = Math.floor(Math.random() * itemsCount);
            const item = items[slot];
            if (!item) {
              entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
              this.removeTriggeredContainer(containerBlock);
              return;
            }
            entity.runCommand(`/replaceitem entity @s slot.weapon.mainhand 0 ${item.identifier} 1`);
            entity.triggerEvent(Raccoon.HOLDING_ITEM_EVENT);
            const newAmount = item.stack.amount - 1;
            if (newAmount === 0) {
              inventory.setItem(item.slot, null);
            } else {
              item.stack.amount = newAmount;
              inventory.setItem(item.slot, item.stack);
            }
            this.removeTriggeredContainer(containerBlock);
          } catch {
            if (entity?.isValid()) {
              entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
            }
            this.removeTriggeredContainer(containerBlock);
          }
        }, 20 * waitTime);
      } catch {
        if (e.sourceEntity?.isValid()) {
          e.sourceEntity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
        }
      }
    });
  }
  onCancelSearchingItemOnChest() {
    system.afterEvents.scriptEventReceive.subscribe((e) => {
      const entity = e.sourceEntity;
      if (entity == null || entity.typeId !== Raccoon.IDENTIFIER || e.id !== Raccoon.CANCEL_SEARCHING_ITEM_EVENT) return;
      const triggeredContainer = Raccoon.TRIGGERED_CONTAINERS.find(container => container.entity === entity);
      if (triggeredContainer) {
        this.removeTriggeredContainer(triggeredContainer.block);
      }
      entity.triggerEvent(Raccoon.SEARCH_CONTAINER_DELAY_EVENT);
    });
  }
  removeTriggeredContainer(block) {
    const index = Raccoon.TRIGGERED_CONTAINERS.findIndex((container) => 
      Helper.compareVector3(container.block.location, block.location)
    );
    if (index !== -1) {
      Raccoon.TRIGGERED_CONTAINERS.splice(index, 1);
    }
  }
  getTriggeredContainerIdentifier(block) {
    return Raccoon.VALID_CONTAINERS.find((container) => block?.permutation.matches(container)).replace('minecraft:', '');
  }
  isValidContainer(block) {
    return Raccoon.VALID_CONTAINERS.find((container) => block?.permutation.matches(container)) ?? false;
  }
}
new Raccoon();