import * as mc from "@minecraft/server";
import * as utils from "../../utils/index";
import * as comp from "../components/index";
import { BotBase } from "../bot";
export const SPRINKLER_MAX_FUEL = 64;
export const SPRINKLER_FUEL_ITEM = "minecraft:bone_meal";
const MIN_DELAY_SECONDS = 2.0;
const MAX_DELAY_SECONDS = 5.0;
const CROP_TYPES = [
    "minecraft:wheat",
    "minecraft:beetroot",
    "minecraft:carrots",
    "minecraft:potatoes",
    "minecraft:sweet_berry_bush",
    "minecraft:nether_wart",
];
export class SprinklerBot extends BotBase {
    constructor() {
        super(...arguments);
        this.active = this.getProperty("active");
    }
    get Active() {
        return this.active;
    }
    set Active(v) {
        this.active = v;
        this.setProperty("active", v);
    }
    onConstructed() {
        super.onConstructed();
        this.addActorComponent(comp.BotFuelComponent, { fuelItem: SPRINKLER_FUEL_ITEM, max: SPRINKLER_MAX_FUEL });
        this.addActorComponent(comp.HopperComponent, {
            pullCallbacks: () => new Map([["minecraft:bone_meal", this.pullFuelFromHopper.bind(this)]]),
            pullCondition: () => this.Fuel < 64,
            pullFrequencySeconds: 1,
        });
    }
    onFuelRestored() {
        this.dimension.playSound(utils.addName("entity.bot.add_bonemeal_fuel"), this.location);
        this.growthLoop();
    }
    onFuelExhausted() {
        this.Active = false;
        this.dimension.playSound(utils.addName("entity.bot.power_down"), this.location);
    }
    pullFuelFromHopper(fuel) {
        if (this.Fuel < 64) {
            this.Fuel++;
            return true;
        }
        return false;
    }
    async growthLoop() {
        while (this.isValid() && this.Fuel > 0) {
            this.Active = false;
            await utils.waitForTicks(utils.getRandomInteger(MIN_DELAY_SECONDS, MAX_DELAY_SECONDS));
            if (this.isValid() && this.Fuel > 0) {
                const crops = await this.getGrowableCrops();
                if (crops.length && this.isValid()) {
                    this.Fuel--;
                    this.Active = true;
                    await utils.waitForTicks(20);
                    await this.growCrops(crops);
                }
            }
        }
        this.Active = false;
    }
    async getGrowableCrops() {
        let crops = [];
        await utils.iterateOverBlocks(this.dimension, this.location, 16, (block) => {
            if (CROP_TYPES.includes(block.typeId)) {
                try {
                    const growth = Number(block.permutation.getState('growth'));
                    if (growth < 7)
                        crops.push(block);
                }
                catch (error) { }
            }
            return false;
        });
        return crops;
    }
    async growCrops(crops) {
        const randomSelection = utils.getRandomInteger(1, crops.length);
        for (let index = 0; index < randomSelection; index++) {
            try {
                const block = utils.getRandomArrayEntry(crops);
                const growth = Number(block.permutation.getState('growth')) + 1;
                if (growth <= 7) {
                    block.setPermutation(mc.BlockPermutation.resolve(block.typeId, { growth }));
                    block.dimension.spawnParticle('ldz_240927:crop_growth_emitter', new utils.Vector3(block.location).add(0.5));
                }
                utils.removeFromArray(crops, block);
            }
            catch (error) { }
        }
        if (this.Fuel <= 0)
            return;
        await utils.waitForTicks(20);
        if (this.Fuel <= 0)
            return;
    }
}
utils.Actor.makeActors({ type: "ldz_240927:sprinkler_bot" }, SprinklerBot);
