/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.bausystem.features.util;

import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import yapion.hierarchy.types.YAPIONObject;
import yapion.hierarchy.types.YAPIONValue;

@Linked
public class TNTClickListener extends SWCommand implements Listener {

    public static final String TNT_CLICK_DETAILS = "tnt_click_details";

    public TNTClickListener() {
        super("tntdetails");
    }

    @Register(description = "TNT_DETAILS_COMMAND")
    public void toggle(Player player) {
        YAPIONObject yapionObject = Config.getInstance().get(player);
        if (yapionObject.getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) {
            yapionObject.put(TNT_CLICK_DETAILS, false);
            BauSystem.MESSAGE.send("TNT_DETAILS_OFF", player);
        } else {
            yapionObject.put(TNT_CLICK_DETAILS, true);
            BauSystem.MESSAGE.send("TNT_DETAILS_ON", player);
        }
    }

    @EventHandler
    public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
        if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
        if (event.getHand() != EquipmentSlot.HAND) return;
        if (!Config.getInstance().get(event.getPlayer()).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) return;

        Entity entity = event.getRightClicked();
        if (event.getRightClicked() instanceof TNTPrimed) {
            TNTPrimed tntPrimed = (TNTPrimed) entity;
            long count = Bukkit.getWorlds().get(0).getEntitiesByClass(TNTPrimed.class).stream().filter(e -> e.getLocation().distanceSquared(tntPrimed.getLocation()) < 0.1).count();
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", event.getPlayer());
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_ORDER", event.getPlayer(), getOrder(tntPrimed));
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_FUSE_TIME", event.getPlayer(), tntPrimed.getFuseTicks());
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_X", event.getPlayer(), tntPrimed.getLocation().getX() + "");
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Y", event.getPlayer(), tntPrimed.getLocation().getY() + "");
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_POSITION_Z", event.getPlayer(), tntPrimed.getLocation().getZ() + "");
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_X", event.getPlayer(), tntPrimed.getVelocity().getX() + "");
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Y", event.getPlayer(), tntPrimed.getVelocity().getY() + "");
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_VELOCITY_Z", event.getPlayer(), tntPrimed.getVelocity().getZ() + "");
            BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_COUNT", event.getPlayer(), count + "");
        }
    }

    private int getOrder(Entity entity) {
        return entity.getEntityId() - entity.getLocation().getWorld().getEntities().stream().filter(TNTPrimed.class::isInstance).map(Entity::getEntityId).min(Integer::compareTo).orElse(0);
    }
}
