let configPATH = "./plugins/QC_clean/config/config.json"
let task = 0
let CENUM = 0
let playerclean = 0
let config = null
let interval = null;
mc.listen("onServerStarted", () => {
    if (File.exists(configPATH)) {
        config = JSON.parse(File.readFrom(configPATH))
        logger.info(`\x1b[92m>> QC_clean 配置文件已加载 <<\x1b[0m`)
        logger.info(`\x1b[94m周期清理启用状态：\x1b\x1b[33m${config["QC_clean"]["enable"]}\x1b[0m`)
        logger.info(`\x1b[94m玩家清理启用状态：\x1b\x1b[33m${config["QC_clean"]["PlayerClean"]["enable"]}\x1b[0m`)
        logger.info(`\x1b[94m自动清理启用状态：\x1b\x1b[33m${config["QC_clean"]["AUTO_clean"]["enable"]}\x1b[0m`)
        startinterval()
        creatcmd()
    } else {
        //预释放配置文件，勿动！！
        try {
            new JsonConfigFile(configPATH).init("QC_clean", {
                enable: true,
                interval: 600,
                whitelist: [
                    "^minecraft:netherite_",
                    "^minecraft:ancient_debris$",
                    "^minecraft:dragon_egg$",
                    "^minecraft:nether_star$",
                    "^minecraft:elytra$",
                    "^minecraft:emerald$",
                    "^minecraft:beacon$",
                    "^minecraft:ender_eye$",
                    "^minecraft:shulker_box$",
                    "^minecraft:sea_lantern$",
                    "^minecraft:enchanted_book$",
                    "^minecraft:diamond",
                    "^minecraft:totem_of_undying$",
                    "^minecraft:ender_pearl$",
                    "^minecraft:ender_crystal$",
                    "^minecraft:ender_dragon$",
                    "^minecraft:chest_minecart$",
                    "^minecraft:minecart$",
                    "^minecraft:hopper_minecart$",
                    "^minecraft:boat$",
                    "^minecraft:armor_stand$"
                ],
                AUTO_clean: {
                    enable: true,
                    threshold: 500,
                },
                PlayerClean: {
                    enable: true,
                    Cooldown: 120
                },
                notice: {
                    notice1: 30,
                    notice2: 10
                },
                LowTpsClean: {
                    enable: true,
                    minimum: 15
                },
                clean_Cmd: "clean"
            });
            //预释放配置文件，勿动！！
            colorLog("yellow", `配置文件已生成，请前往${configPATH}修改配置！注意再次重启插件生效！`)
            config = JSON.parse(File.readFrom(configPATH))
        } catch (error) {
            logger.error(error)
        }
    }
});

function startinterval() {
    if (!config["QC_clean"]["enable"]) return;
    setInterval(() => clean(""), config["QC_clean"]["interval"] * 1000);
}

function sendNotification(message, delay) {
    setTimeout(() => {
        let allplayer = mc.getOnlinePlayers(); 
        allplayer.forEach((player) => {
            if (!player.isSimulatedPlayer()) {
                player.sendToast("§b§lQC_clean", message);
                player.tell(`§b§lQC_clean §7 >> ${message}`, 0);
            }
        })
    }, delay);
}

function clean(ori, out) {
    if (task == 0) {
        task = 1;
        let notice1 = config["QC_clean"]["notice"]["notice1"]
        let notice2 = config["QC_clean"]["notice"]["notice2"]
        sendNotification(`§e请注意！  §l§a${notice1} 秒 §r§e后清理实体，请捡起贵重物品！`, 0)
        sendNotification(`§e请注意！  §l§a${notice2} 秒 §r§e后清理实体，请捡起贵重物品！`, (notice1 - notice2) * 1000)
        setTimeout(() => discleancmd(), notice1 * 1000)
    }
}

function discleancmd(){
    CENUM = 0
    let allentity = mc.getAllEntities()
    allentity.forEach((entity) => {
        let ETObject = entity.isItemEntity() ? entity.toItem() : entity;
        let isWhitelisted = config["QC_clean"]["whitelist"].some(pattern => new RegExp(pattern).test(ETObject.type))
        if (isWhitelisted || 
            (entity.getNbt() && (entity.getNbt().toObject().IsTamed || entity.getNbt().toObject().CustomName)) || 
            (entity.hasContainer() && !(entity.getContainer()).isEmpty()) || 
            entity.isTrusting) {
            return;
        }        
        CENUM++;
        entity.despawn()
    })
    setTimeout(() => task = 0, 3000)
    sendNotification(`§r§a已成功清理 §r§l${CENUM} §r§a个实体`, 0)
}

mc.listen("onTick", () => {
    if (interval === null) {
        interval = setInterval(() => {
            if (config["QC_clean"]["LowTpsClean"]["enable"] && parseFloat(getCurrentTps()) <= config["QC_clean"]["LowTpsClean"]["minimum"] && task == 0) {
                mc.broadcast(`§b§lQC_clean §7 >> §r§c服务器TPS过低,已自动执行清理操作.`);
                clean("")
            }
            let cleanableEntities = mc.getAllEntities().filter(entity => {
                let ETObject = entity.isItemEntity() ? entity.toItem() : entity;
                let nbt = entity.getNbt() ? entity.getNbt().toObject() : null;
                return !(
                    config["QC_clean"]["whitelist"].some(pattern => new RegExp(pattern).test(ETObject.type)) || 
                    (nbt && (nbt.IsTamed || nbt.CustomName)) || 
                    (entity.hasContainer() && !(entity.getContainer()).isEmpty())
                );
            });
            let ENUM = cleanableEntities.length;
            if (ENUM >= config["QC_clean"]["AUTO_clean"]["threshold"] && task == 0) {
                mc.broadcast(`§b§lQC_clean §7 >> §r§c§l当前实体较多，实体数: §r${ENUM} §c§l个`);
                clean();
            }
        }, 1000);
    }
});

function Beforclean(ori, out) {
    let player = ori.player;
    if (task == 1) {
        (ori.player).tell(`§b§lQC_clean §r§7 >> §c清理任务进行中！`, 0)
        return
    }
    if (player.permLevel === 0 && config["QC_clean"]["PlayerClean"]["enable"]) {
        if (playerclean === 0) {
            playerclean = 1
            setTimeout(() => playerclean = 0, config["QC_clean"]["PlayerClean"]["Cooldown"] * 1000)
            mc.broadcast(`§b§lQC_clean §7 >> §d§l玩家 ${player.realName} 执行了清理操作.`)
            clean(ori, out)
        } else {
            player.tell("§b§lQC_clean §7 >> §c§l操作冷却中！")
        }
    } else {
        clean(ori, out)
    }
}

function getTpsFunction(SAMPLE_SIZE = 20) {
    let eventCount = 0;
    let startTime = Date.now();
    let lastTps = '20.00';
    function calculateTps() {
        const milliseconds = Date.now() - startTime;
        const seconds = milliseconds / 1000;
        return Math.min(SAMPLE_SIZE / seconds, 20).toFixed(2);
    }
    mc.listen("onTick", () => {
        eventCount++;
        if (eventCount >= SAMPLE_SIZE) {
            lastTps = calculateTps();
            eventCount = 0;
            startTime = Date.now();
        }
    });
    return function() {
        return lastTps;
    };
}
let getCurrentTps = getTpsFunction();

function showtps(ori) {
    ori.player.tell(`§b§lQC_clean §7 >> §e§l当前服务器TPS： §d${getCurrentTps()}`)
}

function creatcmd() {
	try {
		const commands = [
			{ name: config["QC_clean"]["clean_Cmd"], description: "清理实体与掉落物", callback: Beforclean },
            { name: `${config["QC_clean"]["clean_Cmd"]}tps`, description: "查看服务器TPS", callback: showtps }
		];
		commands.forEach((command) => {
			const cmd = mc.newCommand(command.name, command.description, PermType.Any)
			cmd.setCallback((_cmd, ori, out, _res) => {
				command.callback(ori, out)
			});
			cmd.overload([])
			cmd.setup()
		});
	} catch (error) {
		logger.error("命令注册失败！请查看是否有其它插件占用主命令！错误信息：" + error);
	}
}