package de.viper.survivalplus.listeners;

import de.viper.survivalplus.SurvivalPlus;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.HashMap;
import java.util.List;
import java.util.UUID;

public class GraveListener implements Listener {

    private final SurvivalPlus plugin;
    private final HashMap<Location, UUID> graveOwners = new HashMap<>();
    private final HashMap<Location, UUID> graveArmorStands = new HashMap<>();
    private long despawnTime;

    public GraveListener(SurvivalPlus plugin) {
        this.plugin = plugin;
        reloadConfig(plugin.getConfig());
    }

    public void reloadConfig(FileConfiguration config) {
        this.despawnTime = config.getLong("graves.despawn-time", 1800);
    }

    @EventHandler
    public void onPlayerDeath(PlayerDeathEvent event) {
        if (event.getKeepInventory()) return;

        Player player = event.getEntity();
        UUID playerId = player.getUniqueId();
        FileConfiguration gravesConfig = plugin.getGravesConfig();
        FileConfiguration lang = plugin.getLangConfig();

        Location deathLocation = player.getLocation().clone();
        Block block = deathLocation.getBlock();

        // Save to graves.yml
        gravesConfig.set("graves." + playerId + ".world", deathLocation.getWorld().getName());
        gravesConfig.set("graves." + playerId + ".x", deathLocation.getX());
        gravesConfig.set("graves." + playerId + ".y", deathLocation.getY());
        gravesConfig.set("graves." + playerId + ".z", deathLocation.getZ());
        plugin.saveGravesConfig();

        // Suche Platz für Truhe
        if (block.isEmpty() || block.getType().isAir()) {
            block.setType(Material.CHEST);
        } else {
            for (int i = 1; i <= 10; i++) {
                Block above = block.getRelative(0, i, 0);
                if (above.isEmpty() || above.getType().isAir()) {
                    above.setType(Material.CHEST);
                    block = above;
                    deathLocation = block.getLocation();
                    break;
                }
            }
        }

        if (block.getType() == Material.CHEST) {
            Chest chest = (Chest) block.getState();
            for (ItemStack item : event.getDrops()) {
                if (item != null && item.getType() != Material.AIR) {
                    chest.getInventory().addItem(item);
                }
            }
            event.getDrops().clear();

            graveOwners.put(block.getLocation(), playerId);

            // Nachricht an Spieler
            player.sendMessage(String.format(
                lang.getString("graves.created", "§aDein Grab wurde bei x=%.2f, y=%.2f, z=%.2f erstellt!"),
                deathLocation.getX(),
                deathLocation.getY(),
                deathLocation.getZ()
            ));

            // ArmorStand mit "Grab von <Name>"
            Location standLocation = deathLocation.clone().add(0.5, 1.2, 0.5);
            ArmorStand stand = deathLocation.getWorld().spawn(standLocation, ArmorStand.class);
            stand.setVisible(false);
            stand.setCustomName("§cGrab von " + player.getName());
            stand.setCustomNameVisible(true);
            stand.setMarker(true);
            stand.setGravity(false);
            stand.setInvulnerable(true);
            stand.setSilent(true);
            stand.setSmall(true);

            // Speichere ArmorStand UUID
            graveArmorStands.put(block.getLocation(), stand.getUniqueId());

            // Entfernen nach Zeit
            if (despawnTime >= 0) {
                final Block graveBlock = block;
                final Location graveLocation = graveBlock.getLocation();
                final Player deadPlayer = player;
                final FileConfiguration langConfigFinal = lang;

                new BukkitRunnable() {
                    @Override
                    public void run() {
                        if (graveBlock.getType() == Material.CHEST) {
                            graveBlock.setType(Material.AIR);
                            graveOwners.remove(graveLocation);
                            removeArmorStand(graveLocation);

                            deadPlayer.sendMessage(String.format(
                                langConfigFinal.getString("graves.despawned", "§cDein Grab bei x=%.2f, y=%.2f, z=%.2f ist verschwunden!"),
                                graveLocation.getX(),
                                graveLocation.getY(),
                                graveLocation.getZ()
                            ));
                        }
                    }
                }.runTaskLater(plugin, despawnTime * 20L);
            }

            // Überwache, ob Truhe geleert wurde
            final Block chestBlockFinal = block;
            final Player playerFinal = player;
            final FileConfiguration langFinal = lang;

            new BukkitRunnable() {
                @Override
                public void run() {
                    if (chestBlockFinal.getType() != Material.CHEST) {
                        cancel();
                        return;
                    }

                    Chest c = (Chest) chestBlockFinal.getState();
                    boolean empty = true;
                    for (ItemStack item : c.getInventory().getContents()) {
                        if (item != null && item.getType() != Material.AIR) {
                            empty = false;
                            break;
                        }
                    }

                    if (empty) {
                        c.getBlock().setType(Material.AIR);
                        graveOwners.remove(c.getLocation());
                        removeArmorStand(c.getLocation());

                        playerFinal.sendMessage(String.format(
                            langFinal.getString("graves.emptied", "§7Dein Grab bei x=%.2f, y=%.2f, z=%.2f wurde geleert."),
                            (double)c.getX(),
                            (double)c.getY(),
                            (double)c.getZ()
                        ));

                        cancel();
                    }
                }
            }.runTaskTimer(plugin, 20L, 60L);
        }
    }

    private void removeArmorStand(Location chestLocation) {
        UUID standId = graveArmorStands.remove(chestLocation);
        if (standId == null) return;

        Entity entity = Bukkit.getEntity(standId);
        if (entity != null && entity instanceof ArmorStand) {
            entity.remove();
        }
    }

    public boolean isOwner(Player player, Location location) {
        return graveOwners.getOrDefault(location, null) != null &&
               graveOwners.get(location).equals(player.getUniqueId());
    }
}
