/*
 * This file is a part of the SteamWar software.
 *
 * Copyright (C) 2021  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.autostart;

import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionUtils;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.type.Chest;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

@Linked
public class AutostartListener implements Listener {

    @Getter
    public static AutostartListener instance;

    {
        instance = this;
    }

    public static ItemStack getWandItem(Player player) {
        ItemStack itemStack = new SWItem(Material.FIREWORK_STAR, BauSystem.MESSAGE.parse("AUTOSTART_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("AUTOSTART_ITEM_LORE", player)), false, null).getItemStack();
        ItemUtils.setItem(itemStack, "autostart");
        return itemStack;
    }

    @Getter
    private Map<Region, Long> regionStartTime = new HashMap<>();

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
        if (!ItemUtils.isItem(event.getItem(), "autostart")) {
            return;
        }
        if (event.getClickedBlock() == null) {
            return;
        }
        if (event.getClickedBlock().getBlockData() instanceof Chest) {
            return;
        }
        if (event.getClickedBlock().getType() == Material.BEDROCK) {
            event.getClickedBlock().setType(Material.SLIME_BLOCK);
            Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
                event.getClickedBlock().setType(Material.BEDROCK, false);
            }, 1);
        }
        activate(event.getPlayer());
    }

    @EventHandler
    public void onInventoryClose(InventoryCloseEvent event) {
        if (!(event.getPlayer() instanceof Player)) {
            return;
        }
        if(!Permission.BUILD.hasPermission((Player) event.getPlayer())) return;
        if (!ItemUtils.isItem(event.getPlayer().getInventory().getItemInMainHand(), "autostart")) {
            return;
        }
        if (event.getInventory().getLocation() == null) {
            return;
        }
        if (event.getInventory().getLocation().getBlock().getBlockData() instanceof Chest) {
            activate((Player) event.getPlayer());
        }
    }

    public void activate(Player player) {
        Region region = Region.getRegion(player.getLocation());
        if (region.isGlobal()) {
            BauSystem.MESSAGE.send("AUTOSTART_MESSAGE_NO_REGION", player);
            return;
        }
        if (!region.hasType(RegionType.TESTBLOCK)) {
            BauSystem.MESSAGE.send("AUTOSTART_MESSAGE_NO_REGION", player);
            return;
        }
        if (regionStartTime.containsKey(region)) {
            BauSystem.MESSAGE.send("AUTOSTART_MESSAGE_RESET", player);
        } else {
            BauSystem.MESSAGE.send("AUTOSTART_MESSAGE_START", player);
        }
        regionStartTime.put(region, TPSUtils.currentRealTick.get());
    }

    @EventHandler
    public void onEntityExplode(EntityExplodeEvent event) {
        if (regionStartTime.isEmpty()) {
            return;
        }

        event.blockList().forEach(block -> {
            Region region = Region.getRegion(block.getLocation());
            if (!regionStartTime.containsKey(region)) return;
            if (!region.hasType(RegionType.TESTBLOCK)) return;
            if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return;
            long tickDiff = TPSUtils.currentRealTick.get() - regionStartTime.remove(region);
            long preFightDurationInSeconds = getPreFightDurationInSeconds(region);
            RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT1", tickDiff);
            RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT2", preFightDurationInSeconds, ((preFightDurationInSeconds * 20) - tickDiff));
            RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT3");
        });
    }

    private int getPreFightDurationInSeconds(Region region) {
        File file = region.gameModeConfig();
        if (file == null) return 30;
        FileConfiguration config = YamlConfiguration.loadConfiguration(file);
        return config.getInt("Times.PreFightDuration", 30);
    }
}
