/*
 *   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.simulator.gui;

import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.simulator.execute.SimulatorStabGenerator;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui;
import de.steamwar.bausystem.region.Region;
import de.steamwar.data.CMDs;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;

import java.util.Arrays;

public class SimulatorTNTGui extends SimulatorScrollGui<TNTPhase> {

    private TNTElement tnt;
    private SimulatorGroup parent;
    private SimulatorBaseGui back;

    public SimulatorTNTGui(Player player, Simulator simulator, TNTElement tnt, SimulatorGroup parent, SimulatorBaseGui back) {
        super(player, simulator, 6 * 9, tnt.getPhases());
        this.tnt = tnt;
        this.parent = parent;
        this.back = back;
    }

    @Override
    public String baseTitle() {
        return "TNT";
    }

    @Override
    public void headerAndFooter() {
        if (tnt.getPhases().isEmpty()) {
            back.open();
            SimulatorWatcher.update(simulator);
            return;
        }

        tnt.sort();

        // Back Arrow
        inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> {
            if (parent.getElements().contains(tnt)) {
                back.open();
            } else {
                SimulatorGroup newParent = tnt.getGroup(simulator);
                if (newParent == null) {
                    player.closeInventory();
                    return;
                }
                SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
                if (newParent.getElements().size() == 1) {
                    simulatorGui.open();
                } else {
                    new SimulatorGroupGui(player, simulator, newParent, simulatorGui).open();
                }
            }
        }).setCustomModelData(CMDs.BACK));

        inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> {
            tnt.getPhases().clear();
            SimulatorWatcher.update(simulator);
        }).setCustomModelData(CMDs.Simulator.DELETE));

        // Material Chooser
        inventory.setItem(4, tnt.toItem(player, clickType -> {
            new SimulatorMaterialGui(player, simulator, tnt::getMaterial, tnt::setMaterial, this).open();
        }));

        inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> {
            new SimulatorTNTSettingsGui(player, simulator, tnt, this).open();
        }).setCustomModelData(CMDs.Simulator.SETTINGS));
        inventory.setItem(48, new SWItem(tnt.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, tnt.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> {
            tnt.setDisabled(!tnt.isDisabled());
            SimulatorWatcher.update(simulator);
        }).setCustomModelData(CMDs.Simulator.ENABLED_OR_DISABLED));
        inventory.setItem(49, new SWItem(Material.CALIBRATED_SCULK_SENSOR, "§eCreate Stab", click -> {
            new SimulatorAnvilGui<>(player, "Depth Limit", "", Integer::parseInt, depthLimit -> {
                if (depthLimit <= 0) return false;
                simulator.setStabGenerator(new SimulatorStabGenerator(Region.getRegion(player.getLocation()), simulator, tnt, depthLimit));
                SimulatorWatcher.update(simulator);
                return true;
            }, null).open();
        }).setCustomModelData(CMDs.Simulator.CREATE_STAB));
        inventory.setItem(50, new SWItem(Material.CHEST, parent.getElements().size() == 1 ? "§eMake Group" : "§eAdd another TNT to Group", clickType -> {
            TNTElement tntElement = new TNTElement(tnt.getPosition().clone());
            tntElement.add(new TNTPhase());
            parent.add(tntElement);
            new SimulatorGroupGui(player, simulator, parent, new SimulatorGui(player, simulator)).open();
            SimulatorWatcher.update(simulator);
        }).setCustomModelData(CMDs.Simulator.MAKE_GROUP));
        inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> {
            new SimulatorGroupChooserGui(player, simulator, tnt, tnt.getGroup(simulator), this).open();
        }).setCustomModelData(CMDs.Simulator.JOIN_GROUP));
    }

    @Override
    public SWItem[] column(TNTPhase tntSetting, int index) {
        SWItem tnt = new SWItem(Material.TNT, "§eTNT§8:§7 " + tntSetting.getCount(), Arrays.asList("§7Tick§8: §e" + tntSetting.getTickOffset(), "§7Fuse§8:§e " + tntSetting.getLifetime(), "", "§7Order§8:§e " + tntSetting.getOrder(), "", "§7X-Jump§8: " + (tntSetting.isXJump() ? "§aOn" : "§cOff"), "§7Y-Jump§8: " + (tntSetting.isYJump() ? "§aOn" : "§cOff"), "§7Z-Jump§8: " + (tntSetting.isZJump() ? "§aOn" : "§cOff"), "", "§7Click§8:§e Edit", "§7Middle-Click§8:§e Remove"), false, clickType -> {
            if (clickType == ClickType.MIDDLE) {
                this.tnt.getPhases().remove(tntSetting);
                SimulatorWatcher.update(simulator);
            } else {
                new SimulatorTNTPhaseSettingsGui(player, simulator, this.tnt, tntSetting, this).open();
            }
        });
        tnt.getItemStack().setAmount(Math.min(tntSetting.getCount(), 64));

        return new SWItem[]{
                new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
                    if (clickType == ClickType.DOUBLE_CLICK) return;
                    tntSetting.setCount(tntSetting.getCount() + (clickType.isShiftClick() ? 5 : 1));
                    SimulatorWatcher.update(simulator);
                }).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
                tnt,
                new SWItem(tntSetting.getCount() > 1 ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
                    if (clickType == ClickType.DOUBLE_CLICK) return;
                    tntSetting.setCount(Math.max(1, tntSetting.getCount() - (clickType.isShiftClick() ? 5 : 1)));
                    SimulatorWatcher.update(simulator);
                }).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
                new SWItem(Material.ANVIL, "§eEdit Phase", clickType -> {
                    new SimulatorTNTPhaseSettingsGui(player, simulator, this.tnt, tntSetting, this).open();
                }).setCustomModelData(CMDs.Simulator.EDIT_ACTIVATION),
        };
    }

    @Override
    public SWItem[] lastColumn() {
        return new SWItem[]{
                new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
                    addNewPhase(clickType.isShiftClick());
                }).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
                new SWItem(Material.GUNPOWDER, "§eTNT§8:§a New Phase", clickType -> {
                    addNewPhase(false);
                }).setCustomModelData(CMDs.Simulator.NEW_PHASE),
                new SWItem(Material.GRAY_DYE, "§7", clickType -> {
                }).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
        };
    }

    private void addNewPhase(boolean shift) {
        TNTPhase lastElement = tnt.getPhases().get(tnt.getPhases().size() - 1);
        TNTPhase newPhase = new TNTPhase(lastElement.getTickOffset() + 1);
        if (shift) newPhase.setCount(newPhase.getCount() + 5);
        scroll++;
        tnt.add(newPhase);
        SimulatorWatcher.update(simulator);
    }
}
