let cleaningTime = 1200 * 30;

let timerOn = true;
let timerCheck = 0;
let lastClearLagResult = Utils.newList();
let lastTotalClearLagResult = Utils.newCountingMap();

let timer = 0;

let clearLag =(server) => {
    let itemList = server.getEntities().filter(entity => entity.type.equals('minecraft:item'));
    let lastResult = Utils.newCountingMap();

    lastClearLagResult.clear();
    lastTotalClearLagResult.clear();

    itemList.forEach(items => {
        var key = items.name;
        lastResult.add(key, 1);
        lastTotalClearLagResult.add(key, items.item.count);
        items.kill();
    });

    lastClearLagResult.addAll(lastResult.entries);
    lastClearLagResult.sort(null);

    server.tell(`${lastTotalClearLagResult.totalCount} Removed items.`);
}

ServerEvents.tick((event) => {
    if(timerOn) {
        timer++;
        if (timer > cleaningTime) {
            clearLag(event.server);
            timer = 0;
        } else if (timer % timerCheck === 0 ) {
            let nextItems = event.server.getEntities().filter(entity => entity.type.equals('minecraft:item')).length;
            event.server.tell(`[ClearLag] Removing ${nextItems} items in ${(cleaningTime - timer) / 1200} minutes!`);
        }
    }
});

ServerEvents.commandRegistry(event => {
    const {commands: Commands, arguments: Arguments} = event;
    event.register(Commands.literal('clearlag').executes(sender => {
        let server = sender.source.getServer();
        clearLag(server);
        return 1;
    }));
    event.register(Commands.literal('clearlagResults').executes(sender => {
        let server = sender.source.getServer();
        server.tell('[ ClearLag Report ]');
        lastClearLagResult.forEach(results => {
            server.tell(['[ ', results.key, ': ', results.value, ' ]'])      
        });
        return 1;
    }));
    event.register(Commands.literal('timerCheck').then(Commands.argument('value', Arguments.FLOAT.create(event)).executes(ctx => {
        const time = Arguments.FLOAT.getResult(ctx, 'value') * 1200;
        timerCheck = time;
        return 1;
    })));
    event.register(Commands.literal('timer').then(Commands.argument('value', Arguments.INTEGER.create(event)).executes(ctx => {
        const time = Arguments.INTEGER.getResult(ctx, 'value') * 1200;
        cleaningTime = time;
        return 1;
    })));
    event.register(Commands.literal('timerOn').then(Commands.argument('value', Arguments.BOOLEAN.create(event)).executes(ctx => {
        const timeOn = Arguments.BOOLEAN.getResult(ctx, 'value');
        timerOn = timeOn;
        return 1;
    })));
});