let cleaningTime = 1200 * 30;
let timerCheck = 1200;
let timerOn = true;

// Notification times, times the user want to get the message how many minutes lasts
const notifications = [30, 10, 1];

let round = 0;
let lastClearLagResult = Utils.newList();
let lastTotalClearLagResult = Utils.newCountingMap();

let blacklist = [
    'minecraft:stick'
];
let clearLag =(server, reset) => {
    let itemList = server.getEntities().filter(entity => entity.type.equals('minecraft:item'));
    let lastResult = Utils.newCountingMap();

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

    itemList.forEach(items => {
        if(!blacklist.includes(items.getFullNBT().Item.id)) {
            var key = items.name;
            lastResult.add(key, items.item.count);
            lastTotalClearLagResult.add(key, items.item.count);
            items.kill();
        }
    });

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

    server.tell([Text.green('[ClearLag] ' ), `${lastTotalClearLagResult.totalCount}`, ' Removed items.']);
    if(reset) round = 0;
}
let timeSchedule = (server) => {
    if(timerOn) {
        server.tell([Text.green('[ClearLag]'),' ClearLag is turned on!']);
        server.scheduleInTicks(timerCheck, callback => {
            let currentTime = timerCheck*++round;
            let nextItems = server.getEntities().filter(entity => entity.type.equals('minecraft:item')).length;

            // The time left until cleaning of items
            let minutesLeft = (cleaningTime - currentTime) / 1200

            if(cleaningTime <= currentTime) {
                clearLag(server, true);
                if (!timerOn) {
                    server.tell([Text.green('[ClearLag]'),' ClearLag is turned off!']);
                    timerOnChanged = false;
                } 
            }
            if (timerCheckChange) {
                timerCheckChange = false;
                round = 0;
                server.tell([Text.green('[ClearLag]'),' TimerCheck got updated to ', `${timerCheck/1200}`, '!']);
            }else if (cleaningTimeChange) {
                cleaningTimeChange = false;
                round = 0;
                server.tell([Text.green('[ClearLag]'),' Timer got updated to ', `${cleaningTime/1200}`, '!']);
            } else if (notifications.includes(minutesLeft)) 
                server.tell([Text.green('[ClearLag]'), ' Removing ', `${nextItems}`, ' items in ', `${minutesLeft}`, ' minutes!']);
            if(timerOn) callback.reschedule();
        })
    }
}

ServerEvents.loaded(event => {
    timeSchedule(event.server);
});

let cleaningTimeChange = false;
let timerCheckChange = false;

ServerEvents.commandRegistry(event => {
    const {commands: Commands, arguments: Arguments} = event;
    event.register(
        Commands.literal('clearlag')
        .then(Commands.literal('clear').executes(ctx => {
            let server = ctx.source.getServer();
            clearLag(server, false);
            return 1;
        }))
        .then(Commands.literal('result').executes(ctx => {
            let server = ctx.source.getServer();
            server.tell([Text.green('[ClearLag]'), ' Report:']);
            lastClearLagResult.forEach(results => {
                server.tell(['[ ', results.key, ': ', results.value, ' ]'])      
            });
            return 1;
        }))
        /*
        .then(Commands.literal('interval').then(Commands.argument('integer', Arguments.INTEGER.create(event))).executes(ctx => {
            let server = ctx.source.getServer();
            const time = Arguments.INTEGER.getResult(ctx, 'integer') * 1200;
            timerCheckChange = true;
            timerCheck = time;
            server.tell([Text.green('[ClearLag]'), ' Interval set to ', time, ' minute'])
            return 1;
        }))
        */
        .then(Commands.literal('timer').then(Commands.argument('integer', Arguments.INTEGER.create(event)).executes(ctx => {
            let server = ctx.source.getServer();
            const time = Arguments.INTEGER.getResult(ctx, 'integer') * 1200;
            cleaningTimeChange = true
            cleaningTime = time;
            server.tell([Text.green('[ClearLag]'), ' Timer set to ', time, ' minute'])
            return 1;
        })))
        .then(Commands.literal('timerOn').then(Commands.argument('boolean', Arguments.BOOLEAN.create(event)).executes(ctx => {
            let server = ctx.source.getServer();
            const timeOn = Arguments.BOOLEAN.getResult(ctx, 'boolean');
            if(timerOn === timeOn) return 1;
            timerOn = timeOn;
            if(timerOn) timeSchedule(server);
            server.tell([Text.green('[ClearLag]'), ' ClearLag is ', timerOn])
            return 1;
        })))
    )
});