/*
 *   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.misslewars.items;

import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.misslewars.MissileWars;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class Missile extends SpecialItem {

    private static final World world = new BukkitWorld(Bukkit.getWorlds().get(0));

    private final Clipboard clipboard;
    private final ItemStack item;

    private Missile(File missileFile) {
        String[] strings = missileFile.getName().split("\\.");
        String name = strings[0];
        String material = strings[1];
        if (!material.endsWith("_SPAWN_EGG")) material += "_SPAWN_EGG";
        Material itemType = Material.valueOf(material);

        ClipboardFormat format = ClipboardFormats.findByFile(missileFile);
        try {
            assert format != null;
            clipboard = format.getReader(new FileInputStream(missileFile)).read();
        } catch (IOException e) {
            throw new SecurityException("Corrupt missile");
        }

        List<String> lore = new ArrayList<>();
        lore(lore, strings, 2, "§7Speed");
        lore(lore, strings, 3, "§7Size");

        EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1);
        BlockTypeMask blockTypeMask = new BlockTypeMask(clipboard, BlockTypes.TNT);
        lore.add("§7TNT §8: §e" + e.countBlocks(clipboard.getRegion(), blockTypeMask));

        item = createItem(itemType, "§c" + name, 1, lore);
    }

    private void lore(List<String> lore, String[] args, int index, String tag) {
        if (args.length > index) {
            lore.add(tag + " §8: §e" + Integer.parseInt(args[index]) + "§8/§77");
        } else {
            lore.add(tag + " §8: §e0§8/§77");
        }
    }

    @Override
    public ItemStack getItem() {
        return item;
    }

    @Override
    public boolean handleUse(Player p) {
        BlockVector3 dimensions = clipboard.getDimensions();
        Location location = p.getLocation();
        BlockVector3 v = BlockVector3.ZERO;
        BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
        AffineTransform aT = new AffineTransform();

        double yaw = (p.getLocation().getYaw() + 360f) % 360;
        if (yaw > 45 && yaw <= 135) aT = aT.rotateY(270);
        else if (yaw > 135 && yaw <= 225) aT = aT.rotateY(180);
        else if (yaw > 225 && yaw <= 315) aT = aT.rotateY(90);

        v = v.subtract(dimensions.x() / 2, dimensions.y() + 2, -2).subtract(offset);
        v = aT.apply(v.toVector3()).toBlockPoint();
        v = v.add(location.getBlockX(), location.getBlockY(), location.getBlockZ());

        EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1);
        ClipboardHolder ch = new ClipboardHolder(clipboard);
        ch.setTransform(aT);
        Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(true).build());
        e.flushSession();
        return true;
    }

    @Override
    public boolean isMissile() {
        return true;
    }

    public static void init() {
        File missileFolder = new File(MissileWars.getPlugin().getDataFolder(), "missiles");
        if (!missileFolder.exists() || !missileFolder.canRead() || !missileFolder.isDirectory()) {
            throw new SecurityException("Missiles could not be loaded");
        }
        for (File missileFile : Objects.requireNonNull(missileFolder.listFiles())) {
            if (!missileFile.canRead() || !missileFile.isFile()) continue;
            if (!missileFile.getName().endsWith(".schem")) continue;
            new Missile(missileFile);
        }
    }

}
