/*
 * Original project: RedEnvelope by KaguyaStudio-MC
 * Original project link: https://github.com/KaguyaStudio-MC/RedEnvelope
 * Modified by: LeisureTimeDock
 * This file is part of RedEnvelope
 * Licensed under Camellia License Version 1.0
 */

package top.leisuretimedock.redenvelope.core.event;

import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import top.leisuretimedock.redenvelope.RedEnvelope;
import top.leisuretimedock.redenvelope.core.command.RECommand;
import top.leisuretimedock.redenvelope.core.config.ServerConfig;
import top.leisuretimedock.redenvelope.core.network.RENetworkHandler;
import top.leisuretimedock.redenvelope.core.capability.RedEnvelopeStorage;
import top.leisuretimedock.redenvelope.core.util.REUtil;
import top.leisuretimedock.redenvelope.core.capability.RECapability;
import top.leisuretimedock.redenvelope.core.util.RedEnvelopeCooldownData;

import java.util.Objects;

public abstract class CommonEventHandler {
    @net.minecraftforge.fml.common.Mod.EventBusSubscriber(modid = RedEnvelope.MOD_ID, bus = net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.FORGE)
    public static class Game extends CommonEventHandler {
        @SubscribeEvent
        public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) {
            Player player = event.getEntity();
            if (player instanceof ServerPlayer serverPlayer) {
                // 获取玩家的 Capability 数据
                serverPlayer.getCapability(RECapability.HONGBAO_STORAGE).ifPresent(storage -> {
                    // 发送存储数据给客户端（需要创建一个同步包）
                    RENetworkHandler.sendToPlayer(new RedEnvelopeStorage(storage).packet(), serverPlayer);
                });
            }
        }

        @SubscribeEvent
        public static void onPlayerExit(PlayerEvent.PlayerLoggedOutEvent event) {
            Player player = event.getEntity();
            if (player instanceof ServerPlayer serverPlayer) {
                serverPlayer.getCapability(RECapability.HONGBAO_STORAGE).ifPresent(storage -> {
                    RedEnvelopeStorage copy = new RedEnvelopeStorage(storage);
                    copy.values().forEach(redEnvelopePacket -> {

                        if (Objects.equals(redEnvelopePacket.extraData().getUUID("from"), serverPlayer.getUUID())) {
                            REUtil.withdraw(Objects.requireNonNull(serverPlayer.getServer()), redEnvelopePacket, REUtil.PLAYER_EXIT);
                        }
                    });
                });
            }
        }

        @SubscribeEvent
        public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
            // 只在服务端且是玩家 tick 结束时处理
            if (event.phase == TickEvent.Phase.END && event.player instanceof ServerPlayer serverPlayer) {
                long gameTime = serverPlayer.level().getGameTime();
                if (gameTime % 100 == 0) {
                    serverPlayer.getCapability(RECapability.HONGBAO_STORAGE).ifPresent(storage -> {
                        RedEnvelopeStorage copy = new RedEnvelopeStorage(storage);
                        copy.values().forEach(hongBaoPacket -> {
                            long packetTime = hongBaoPacket.extraData().getLong("time");
                            long currentTime = System.currentTimeMillis() / 1000;
                            if (packetTime + ServerConfig.TTL.get() < currentTime) {
                                REUtil.withdraw(Objects.requireNonNull(serverPlayer.getServer()), hongBaoPacket, REUtil.TIME_OUT);
                            }
                        });
                    });
                }
            }
        }

        /**
         * On world load.
         *
         * @param event the event
         */
        @SubscribeEvent
        public static void onWorldLoad(LevelEvent.Load event) {
            if (event.getLevel() instanceof ServerLevel serverLevel) {
                // 只在主世界挂载 SavedData
                if (serverLevel.dimension() == Level.OVERWORLD) {
                    RedEnvelopeCooldownData.getOrCreate(serverLevel);
                }
            }
        }

        @SubscribeEvent
        public static void onPlayerChat(ServerChatEvent event) {
            ServerPlayer player = event.getPlayer();
            String message = event.getMessage().getString();

            player.getCapability(RECapability.HONGBAO_STORAGE).ifPresent(storage -> {
                RedEnvelopeStorage copy = new RedEnvelopeStorage(storage);
                copy.values().forEach(redEnvelopePacket -> {
                    if (!redEnvelopePacket.hbtype().equals("spell")) return;
                    if (redEnvelopePacket.extraData().getString("spell").equals(message)) {
                        REUtil.open(player, redEnvelopePacket.uuid());
                    }
                });
            });
        }
        @SubscribeEvent
        public static void onAttachCap(AttachCapabilitiesEvent<Entity> event) {
            RECapability.onAttachPlayerCapabilities(event);
        }
        @SubscribeEvent
        public static void onRegisterCommand (@NotNull RegisterCommandsEvent event) {
            CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();
            RECommand.register(dispatcher);
        }
    }
    @net.minecraftforge.fml.common.Mod.EventBusSubscriber(modid = RedEnvelope.MOD_ID, bus = net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.MOD)
    public static class Mod extends CommonEventHandler {
        @SubscribeEvent
        public static void onRegisterCap(RegisterCapabilitiesEvent event) {
            RECapability.register(event);
        }

    }
}
