/*
 *   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.cannon.depth;

import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Depth {

    private Region region;
    private Vector minVector = null;
    private Vector maxVector = null;
    private int tntCount = 0;

    public Depth(Region region) {
        this.region = region;
    }

    public void update(List<Block> blocks) {
        List<Block> blocksList = blocks.stream()
                .filter(block -> region.getTestblockArea().inRegion(block.getLocation(), true))
                .collect(Collectors.toList());
        tntCount++;
        for (Block block : blocksList) {
            internalUpdate(block);
        }
    }

    public void finish() {
        if (maxVector == null || minVector == null) return;
        Vector dimensions = maxVector.subtract(minVector);
        dimensions.setX(Math.abs(dimensions.getX()));
        dimensions.setY(Math.abs(dimensions.getY()));
        dimensions.setZ(Math.abs(dimensions.getZ()));

        RegionUtils.message(region, player -> {
            if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) {
                player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount));
            }
        });
    }

    private void internalUpdate(Block block) {
        if (minVector == null) {
            minVector = block.getLocation().toVector();
        }
        minVector.setX(Math.min(minVector.getX(), block.getX()));
        minVector.setY(Math.min(minVector.getY(), block.getY()));
        minVector.setZ(Math.min(minVector.getZ(), block.getZ()));

        if (maxVector == null) {
            maxVector = block.getLocation().toVector();
        }
        maxVector.setX(Math.max(maxVector.getX(), block.getX()));
        maxVector.setY(Math.max(maxVector.getY(), block.getY()));
        maxVector.setZ(Math.max(maxVector.getZ(), block.getZ()));
    }

    private static BaseComponent[] getMessage(Player player, int x, int y, int z, int tntCount) {
        final Set<Integer> dimensions = new HashSet<>();
        dimensions.add(x);
        dimensions.add(y);
        dimensions.add(z);

        int max = getMax(dimensions);

        TextComponent headerComponent = new TextComponent(BauSystem.MESSAGE.parse("DEPTH_COUNTER_MESSAGE", player));

        TextComponent depthComponent = new TextComponent(BauSystem.MESSAGE.parse("DEPTH_COUNTER_COUNT", player, x == max ? "§e" : "§7", x, y == max ? "§e" : "§7", y, z == max ? "§e" : "§7", z));
        depthComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{new TextComponent(BauSystem.MESSAGE.parse("DEPTH_COUNTER_HOVER", player))}));

        TextComponent tntComponent = new TextComponent(BauSystem.MESSAGE.parse("DEPTH_COUNTER_TNT", player, tntCount));

        return new BaseComponent[]{headerComponent, depthComponent, tntComponent};
    }

    private static int getMax(Set<Integer> values) {
        return values.stream().max(Integer::compare).orElse(0);
    }
}
