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

import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionUtils;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.TNTMode;
import de.steamwar.bausystem.region.flags.TestblockMode;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.linkage.Linked;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Linked
public class TNTCommand extends SWCommand {

    public TNTCommand() {
        super("tnt");
    }

    @Register(help = true)
    public void genericHelp(Player p, String... args) {
        BauSystem.MESSAGE.sendPrefixless("COMMAND_HELP_HEAD", p, "Tnt");
        BauSystem.MESSAGE.sendPrefixless("REGION_TNT_HELP", p);
        BauSystem.MESSAGE.sendPrefixless("REGION_TNT_HELP_MODE", p);
    }

    @Register(description = "REGION_TNT_HELP")
    public void toggleCommand(@Validator Player p) {
        Region region = Region.getRegion(p.getLocation());
        tntToggle(region, null, null);
    }

    @Register(description = "REGION_TNT_HELP_MODE")
    public void setCommand(@Validator Player p, TNTMode tntMode) {
        Region region = Region.getRegion(p.getLocation());

        String requestedMessage = null;
        switch (tntMode) {
            case ALLOW:
                requestedMessage = getEnableMessage();
                break;
            case DENY:
                requestedMessage = getDisableMessage();
                break;
            case ONLY_TB:
                requestedMessage = getTestblockEnableMessage();
                break;
        }
        tntToggle(region, tntMode, requestedMessage);
    }

    @ClassMapper(value = TNTMode.class, local = true)
    public TypeMapper<TNTMode> tntModeTypeMapper() {
        Map<String, TNTMode> tntModeMapReduced = new HashMap<>();
        tntModeMapReduced.put("an", TNTMode.ALLOW);
        tntModeMapReduced.put("on", TNTMode.ALLOW);
        tntModeMapReduced.put("aus", TNTMode.DENY);
        tntModeMapReduced.put("off", TNTMode.DENY);

        Map<String, TNTMode> tntModeMap = new HashMap<>(tntModeMapReduced);
        tntModeMap.put("testblock", TNTMode.ONLY_TB);
        tntModeMap.put("tb", TNTMode.ONLY_TB);

        return new TypeMapper<>() {
            @Override
            public List<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
                Region region = Region.getRegion(((Player) sender).getLocation());
                if (region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
                    return new ArrayList<>(tntModeMap.keySet());
                } else {
                    return new ArrayList<>(tntModeMapReduced.keySet());
                }
            }

            @Override
            public TNTMode map(CommandSender sender, PreviousArguments previousArguments, String s) {
                Region region = Region.getRegion(((Player) sender).getLocation());
                if (region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
                    return tntModeMap.getOrDefault(s, null);
                } else {
                    return tntModeMapReduced.getOrDefault(s, null);
                }
            }
        };
    }

    private String getEnableMessage() {
        return "REGION_TNT_ON";
    }

    private String getDisableMessage() {
        return "REGION_TNT_OFF";
    }

    private String getTestblockEnableMessage() {
        return "REGION_TNT_TB";
    }

    private void tntToggle(Region region, TNTMode requestedMode, String requestedMessage) {
        if (requestedMode != null && region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
            region.getRegionData().set(Flag.TNT, requestedMode);
            RegionUtils.actionBar(region, requestedMessage);
            return;
        }
        switch (region.getRegionData().get(Flag.TNT).getWithDefault()) {
            case ALLOW:
            case ONLY_TB:
                region.getRegionData().set(Flag.TNT, TNTMode.DENY);
                RegionUtils.actionBar(region, getDisableMessage());
                break;
            case DENY:
                if (region.getRegionData().get(Flag.TESTBLOCK).isNotWithDefault(TestblockMode.NO_VALUE)) {
                    region.getRegionData().set(Flag.TNT, TNTMode.ONLY_TB);
                    RegionUtils.actionBar(region, getTestblockEnableMessage());
                } else {
                    region.getRegionData().set(Flag.TNT, TNTMode.ALLOW);
                    RegionUtils.actionBar(region, getEnableMessage());
                }
                break;
        }
    }
}
