package net.piratjsk.sddls.listeners;

import net.piratjsk.sddls.mount.ProtectedMount;
import net.piratjsk.sddls.signature.Signature;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.Configuration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;

import net.piratjsk.sddls.Sddls;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.projectiles.ProjectileSource;

import java.util.UUID;
import java.util.stream.Collectors;

import static net.piratjsk.sddls.utils.StringUtils.capitalizeFirstLetter;

public final class MountListener implements Listener {

    @EventHandler
    public void onMountAccess(final PlayerInteractEntityEvent event) {
        final ProtectedMount mount = ProtectedMount.fromEntity(event.getRightClicked());
        if (mount.isProtectedFromPlayer(event.getPlayer())) {
            event.setCancelled(true);
            sendNoAccessMessage(event.getPlayer(), mount);
        }
    }

    @EventHandler
    public void onMountDamage(final EntityDamageEvent event) {
        final ProtectedMount mount = ProtectedMount.fromEntity(event.getEntity());
        final Damager damager = getDamager(event);
        if (shouldBeProtected(mount, damager))
            event.setCancelled(true);
    }

    private boolean shouldBeProtected(final ProtectedMount mount, final Damager damager) {
        if (damager.isPlayer()) {
            final Player player = getPlayer(damager);
            return mount.isProtectedFromPlayer(player);
        }
        return mount.isProtectedFromEnvironment();
    }

    private Player getPlayer(final Damager damager) {
        return Bukkit.getPlayer(damager.uuid);
    }

    private void sendNoAccessMessage(final Player player, final ProtectedMount mount) {
        final Configuration config = JavaPlugin.getPlugin(Sddls.class).getConfig();
        final Entity entity = mount.getEntity();
        final String type = entity.getType().toString().toLowerCase().replaceAll("_", "-");
        final String name = entity.getCustomName() != null ? entity.getCustomName() : type;
        final String players = mount.getSaddle().getSignatures().stream()
                .map(Signature::getName)
                .collect(Collectors.joining(", "));
        final String defaultMessage = config.getString("no-access-msg", "&6[Sddls] &7You don't have access to this %mount%.");
        final String message = config.getString("no-access-msg-" + type, defaultMessage)
                .replaceAll("%mount%", type)
                .replaceAll("%Mount%", capitalizeFirstLetter(type))
                .replaceAll("%name%", name)
                .replaceAll("%Name%", capitalizeFirstLetter(name))
                .replaceAll("%players%", players);
        player.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
    }

    private Damager getDamager(final EntityDamageEvent event) {
        if (!(event instanceof EntityDamageByEntityEvent)) return new Damager();
        final EntityDamageByEntityEvent damageEvent = (EntityDamageByEntityEvent) event;
        return new Damager(damageEvent.getDamager());
    }

    private final class Damager {
        private final EntityType type;
        private final UUID uuid;
        Damager() {
            this.type = null;
            this.uuid = null;
        }
        Damager(final Entity entity) {
            this.type = entity.getType();
            this.uuid = entity.getUniqueId();
        }
        boolean isPlayer() {
            return type == EntityType.PLAYER;
        }
    }

}

@@ -336,45 +336,8 @@
 er;%0A
-import org.bukkit.entity.Projectile;%0A
 impo
@@ -649,56 +649,8 @@
 gin;
-%0Aimport org.bukkit.projectiles.ProjectileSource;
 %0A%0Aim
@@ -1376,24 +1376,29 @@
 l Damage
+Deale
 r damage
 r = getD
@@ -1389,16 +1389,21 @@
 r damage
+Deale
 r = getD
@@ -1407,16 +1407,21 @@
 etDamage
+Deale
 r(event)
@@ -1465,16 +1465,21 @@
 , damage
+Deale
 r))%0A    
@@ -1593,32 +1593,37 @@
 final Damage
+Deale
 r damage
 r) %7B%0A       
@@ -1602,32 +1602,37 @@
 ageDealer damage
+Deale
 r) %7B%0A        if 
@@ -1638,16 +1638,21 @@
  (damage
+Deale
 r.isPlay
@@ -1709,16 +1709,21 @@
 r(damage
+Deale
 r);%0A    
@@ -1883,24 +1883,29 @@
 l Damage
+Deale
 r damage
 r) %7B%0A   
@@ -1896,16 +1896,21 @@
 r damage
+Deale
 r) %7B%0A   
@@ -1944,16 +1944,21 @@
 r(damage
+Deale
 r.uuid);
@@ -3135,16 +3135,21 @@
 e Damage
+Deale
 r getDam
@@ -3147,24 +3147,29 @@
 er getDamage
+Deale
 r(final Enti
@@ -3267,16 +3267,21 @@
 w Damage
+Deale
 r();%0A   
@@ -3391,16 +3391,21 @@
 w Damage
+Deale
 r(damage
@@ -3462,16 +3462,21 @@
 s Damage
+Deale
 r %7B%0A    
@@ -3557,16 +3557,21 @@
   Damage
+Deale
 r() %7B%0A  
@@ -3652,16 +3652,21 @@
   Damage
+Deale
 r(final 

rename Damager to DamageDealer and remove unused imports