/*
 * Copyright (c) 2026 盐灯水母
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package com.remains_cave;

import com.remains_cave.attribute.ModAttributes;
import com.remains_cave.block.ModBlocks;
import com.remains_cave.config.RemainsCaveConfig;
import com.remains_cave.datagen.DataGenerators;
import com.remains_cave.dungeon.DungeonPiece;
import com.remains_cave.dungeon.DungeonStructure;
import com.remains_cave.dungeon.tomb.ChallengeManager;
import com.remains_cave.effect.ModEffects;
import com.remains_cave.entity.ModEntities;
import com.remains_cave.item.ModArmorMaterials;
import com.remains_cave.item.ModDataComponents;
import com.remains_cave.item.ModItems;
import com.remains_cave.item.menu.ModMenus;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.levelgen.structure.StructureType;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.neoforge.event.tick.LevelTickEvent;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
import net.neoforged.neoforge.registries.DeferredRegister;

import java.util.function.Supplier;

@Mod(RemainsCaveMod.MODID)
public class RemainsCaveMod {
    public static final String MODID = "remains_cave";
    // 注册结构类型
    public static final DeferredRegister<StructureType<?>> STRUCTURE_TYPES =
            DeferredRegister.create(Registries.STRUCTURE_TYPE, MODID);
    public static final Supplier<StructureType<DungeonStructure>> DUNGEON_STRUCTURE_TYPE =
            STRUCTURE_TYPES.register("dungeon", () -> () -> DungeonStructure.CODEC);

    // 注册结构片段类型
    public static final DeferredRegister<StructurePieceType> STRUCTURE_PIECE_TYPES =
            DeferredRegister.create(Registries.STRUCTURE_PIECE, MODID);
    public static final Supplier<StructurePieceType> DUNGEON_PIECE_TYPE =
            STRUCTURE_PIECE_TYPES.register("dungeon_piece", () -> DungeonPiece::new);

    public RemainsCaveMod(IEventBus modEventBus) {
        ModContainer container = ModLoadingContext.get().getActiveContainer();
        container.registerConfig(ModConfig.Type.COMMON, RemainsCaveConfig.COMMON_SPEC);
        ModDataComponents.DATA_COMPONENT_TYPES.register(modEventBus);
        ModAttributes.ATTRIBUTES.register(modEventBus);
        ModEntities.ENTITY_TYPES.register(modEventBus);
        ModItems.ITEMS.register(modEventBus);
        ModEffects.EFFECTS.register(modEventBus);
        ModCreativeTabs.register(modEventBus);
        ModArmorMaterials.ARMOR_MATERIALS.register(modEventBus);
        ModMenus.MENUS.register(modEventBus);
        ModBlocks.BLOCKS.register(modEventBus);
        ModBlocks.BLOCK_ENTITIES.register(modEventBus);
        STRUCTURE_TYPES.register(modEventBus);
        STRUCTURE_PIECE_TYPES.register(modEventBus);
        DataGenerators.register(modEventBus);
        net.neoforged.neoforge.common.NeoForge.EVENT_BUS.register(RemainsCaveMod.class);
    }
    private static int cleanupAttempts = 0;
    private static boolean cleanupFinished = false;
    private static final int MAX_ATTEMPTS = 5;       // 最多尝试5次
    private static final int RETRY_INTERVAL_TICKS = 20; // 每1秒尝试一次
    @SubscribeEvent
    public static void onServerTick(ServerTickEvent.Post event) {
        if (!cleanupFinished && event.getServer().getTickCount() % RETRY_INTERVAL_TICKS == 0) {
            cleanupAttempts++;
            boolean anyCleaned = false;
            for (ServerLevel level : event.getServer().getAllLevels()) {
                anyCleaned |= ChallengeManager.get(level).forceCleanup(level);
            }
            // 如果本次清理到了任何东西，重置尝试次数（继续尝试直到稳定）
            if (anyCleaned) {
                cleanupAttempts = 0;
            } else if (cleanupAttempts >= MAX_ATTEMPTS) {
                cleanupFinished = true;
            }
        }
    }
    @SubscribeEvent
    public static void onLevelTick(LevelTickEvent.Post event) {
        if (event.getLevel() instanceof ServerLevel serverLevel) {
            ChallengeManager.get(serverLevel).tick(serverLevel);
        }
    }
}