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

import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.Kit;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.linkage.Linked;
import de.steamwar.sql.PersonalKit;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Linked
public class PersonalKitCreator implements Listener {

    private static final Map<HumanEntity, InventoryBackup> openKitCreators = new HashMap<>();

    public PersonalKitCreator() {
        new StateDependentListener(Config.GameModeConfig.Kits.PersonalKits, FightState.Setup, this);
    }

    public static void openKitCreator(Player player, PersonalKit kit) {
        player.closeInventory();
        new InventoryBackup(player, kit);
        new Kit(kit).loadToPlayer(player);
        player.setGameMode(GameMode.CREATIVE);
        FightSystem.getMessage().sendPrefixless("OPEN_INVENTORY_TO_CUSTOMIZE", player, ChatMessageType.ACTION_BAR);
    }

    public static boolean inKitCreator(HumanEntity player) {
        return openKitCreators.containsKey(player);
    }

    public static void closeIfInKitCreator(HumanEntity player) {
        InventoryBackup backup = openKitCreators.get(player);
        if (backup == null) return;

        backup.close();
    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent e) {
        if (!openKitCreators.containsKey(e.getWhoClicked())) return;
        if (Kit.isBadItem(e.getCursor())) {
            e.setCancelled(true);
        }
    }

    @EventHandler
    public void onMoveEvent(PlayerMoveEvent e) {
        InventoryBackup backup = openKitCreators.get(e.getPlayer());
        if (backup == null) return;
        backup.close();
    }

    @EventHandler
    public void onOpenEvent(InventoryOpenEvent e) {
        InventoryBackup backup = openKitCreators.get(e.getPlayer());
        if (backup == null) return;

        InventoryType type = e.getInventory().getType();
        if (type != InventoryType.PLAYER && type != InventoryType.CREATIVE) {
            backup.close();
        }
    }

    @EventHandler
    public void onInventoryClose(InventoryCloseEvent e) {
        InventoryBackup backup = openKitCreators.get(e.getPlayer());
        if (backup == null) return;

        Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), backup::close, 1);
    }

    @EventHandler
    public void onPlayerExit(PlayerQuitEvent e) {
        InventoryBackup backup = openKitCreators.get(e.getPlayer());
        if (backup == null) return;

        backup.close();
    }

    private static class InventoryBackup {
        private final Player player;
        private final PersonalKit kit;
        private final Kit backup;

        private InventoryBackup(Player player, PersonalKit kit) {
            openKitCreators.put(player, this);
            this.player = player;
            this.backup = Kit.getActiveKit(player);
            this.kit = kit;
        }

        private void close() {
            Kit kit1 = new Kit(kit.getName(), player);
            kit1.removeBadItems();


            openKitCreators.remove(player);
            kit1.toPersonalKit(kit);
            backup.loadToPlayer(player);
            player.setGameMode(GameMode.SURVIVAL);
            kit.setInUse();
            player.closeInventory();
            Objects.requireNonNull(Fight.getFightPlayer(player)).setKit(new Kit(kit));
        }
    }
}
