package cat.nyaa.nyaautils.particle;

import cat.nyaa.nyaacore.configuration.ISerializable;
import cat.nyaa.nyaautils.NyaaUtils;
import org.bukkit.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class ParticleData implements ISerializable {
    @Serializable
    public int dustOptions_color = 0;
    @Serializable
    public double dustOptions_size = 0;
    @Serializable
    private Particle particle;
    @Serializable
    private int count;
    @Serializable
    private double offsetX;
    @Serializable
    private double offsetY;
    @Serializable
    private double offsetZ;
    @Serializable
    private double extra;
    @Serializable
    private long freq;
    @Serializable
    private Material material;
    private Map<UUID, Long> lastSend = new HashMap<>();

    public ParticleData() {

    }

    public Particle getParticle() {
        return particle;
    }

    public void setParticle(Particle particle) {
        this.particle = particle;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public double getOffsetX() {
        return offsetX;
    }

    public void setOffsetX(double offsetX) {
        this.offsetX = offsetX;
    }

    public double getOffsetY() {
        return offsetY;
    }

    public void setOffsetY(double offsetY) {
        this.offsetY = offsetY;
    }

    public double getOffsetZ() {
        return offsetZ;
    }

    public void setOffsetZ(double offsetZ) {
        this.offsetZ = offsetZ;
    }

    public double getExtra() {
        return extra;
    }

    public void setExtra(double extra) {
        this.extra = extra;
    }

    public long getFreq() {
        return freq;
    }

    public void setFreq(long freq) {
        this.freq = freq;
    }

    public void sendParticle(UUID uuid, Location loc, ParticleLimit limit, long time) {
        if (!lastSend.containsKey(uuid)) {
            lastSend.put(uuid, 0L);
        }
        if (time - lastSend.get(uuid) >= (freq < limit.getFreq() ? limit.getFreq() : freq) &&
                NyaaUtils.instance.cfg.particles_enabled.contains(particle.name())) {
            lastSend.put(uuid, time);
            double distance = Bukkit.getViewDistance() * 16;
            distance *= distance;
            Object data = getData();
            for (Player player : loc.getWorld().getPlayers()) {
                if (player.isValid() && !NyaaUtils.instance.particleTask.bypassPlayers.contains(player.getUniqueId())
                        && loc.distanceSquared(player.getLocation()) <= distance) {
                    player.spawnParticle(particle, loc,
                            count > limit.getAmount() ? limit.getAmount() : count,
                            offsetX > limit.getOffsetX() ? limit.getOffsetX() : offsetX,
                            offsetY > limit.getOffsetY() ? limit.getOffsetY() : offsetY,
                            offsetZ > limit.getOffsetZ() ? limit.getOffsetZ() : offsetZ,
                            extra > limit.getExtra() ? limit.getExtra() : extra,
                            data);
                }
            }
        }
    }

    public Material getMaterial() {
        return material;
    }

    public void setMaterial(Material material) {
        this.material = material;
    }

    private Object getData() {
        if (particle.getDataType().equals(ItemStack.class)) {
            return new ItemStack(material);
        } else if (particle.getDataType().equals(BlockData.class)) {
            return material.createBlockData();
        } else if (particle.getDataType().equals(Particle.DustOptions.class)) {
            return new Particle.DustOptions(Color.fromRGB(dustOptions_color), (float) dustOptions_size);
        } else {
            return null;
        }
    }
}

@@ -183,16 +183,70 @@
 ckData;%0A
+import org.bukkit.configuration.ConfigurationSection;%0A
 import o
@@ -966,16 +966,48 @@
 Map%3C%3E();
+%0A    private Object data = null;
 %0A%0A    pu
@@ -2524,45 +2524,8 @@
 ce;%0A
-            Object data = getData();%0A
     
@@ -3301,20 +3301,25 @@
         
-d
+getD
 ata
+()
 );%0A     
@@ -3558,24 +3558,129 @@
 %0A        if 
+(data != null %7C%7C particle.getDataType().equals(Void.class)) %7B%0A            return data;%0A        %7D else if 
 (particle.ge
@@ -3710,24 +3710,65 @@
 Stack.class)
+ && material != null && material.isItem()
 ) %7B%0A        
@@ -3767,30 +3767,30 @@
             
-return
+data =
  new ItemSta
@@ -3864,24 +3864,66 @@
 kData.class)
+ && material != null && material.isBlock()
 ) %7B%0A        
@@ -3918,38 +3918,38 @@
 ) %7B%0A            
-return
+data =
  material.create
@@ -4053,22 +4053,22 @@
         
-return
+data =
  new Par
@@ -4159,39 +4159,416 @@
    %7D
- else %7B%0A            return
+%0A        return data;%0A    %7D%0A%0A    @Override%0A    public void serialize(ConfigurationSection config) %7B%0A        ISerializable.serialize(config, this);%0A        config.set(%22version%22, Bukkit.getVersion());%0A    %7D%0A%0A    @Override%0A    public void deserialize(ConfigurationSection config) %7B%0A        if (config.getString(%22version%22, %22%22).length() == 0) %7B%0A            String materialName = config.getString(%22material%22,
  null
+)
 ;%0A  
@@ -4569,22 +4569,524 @@
 l);%0A        
-%7D
+    if (materialName != null) %7B%0A                Material m = Material.matchMaterial(materialName, true);%0A                if (m.isBlock() && config.isInt(%22dataValue%22)) %7B%0A                    config.set(%22material%22, Bukkit.getUnsafe().fromLegacy(m, (byte) config.getInt(%22dataValue%22)).getMaterial().name());%0A                %7D else %7B%0A                    config.set(%22material%22, Bukkit.getUnsafe().fromLegacy(m).name());%0A                %7D%0A            %7D%0A        %7D%0A        ISerializable.deserialize(config, this);
 %0A    %7D%0A%7D%0A

support legacy material name