package com.elmakers.mine.bukkit.utility.platform.v1_16;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Fox;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.SmithingRecipe;

import com.elmakers.mine.bukkit.utility.platform.Platform;

import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;

public class CompatibilityUtils extends com.elmakers.mine.bukkit.utility.platform.v1_15.CompatibilityUtils {
    private final Pattern hexColorPattern = Pattern.compile("&(#[A-Fa-f0-9]{6})");

    public CompatibilityUtils(Platform platform) {
        super(platform);
    }

    @Override
    public void sendChatComponents(CommandSender sender, String containsJson) {
        List<BaseComponent> components = new ArrayList<>();
        String[] pieces = getComponents(containsJson);
        for (String component : pieces) {
            List<BaseComponent> addToComponents = components;
            if (!components.isEmpty()) {
                BaseComponent addToComponent = components.get(components.size() - 1);
                addToComponents = addToComponent.getExtra();
                if (addToComponents == null) {
                    addToComponents = new ArrayList<>();
                }
                addToComponent.setExtra(addToComponents);
            }
            try {
                if (component.startsWith("{")) {
                    addToComponents.addAll(Arrays.asList(ComponentSerializer.parse(component)));
                } else {
                    addToComponents.addAll(Arrays.asList(TextComponent.fromLegacyText(component)));
                }
            } catch (Exception ex) {
                platform.getLogger().log(Level.SEVERE, "Error parsing chat components from: " + component, ex);
            }
        }
        sender.spigot().sendMessage(components.toArray(new BaseComponent[0]));
    }

    @Override
    public String translateColors(String message) {
        message = super.translateColors(message);
        Matcher matcher = hexColorPattern.matcher(message);
        StringBuffer buffer = new StringBuffer(message.length() + 4 * 8);
        while (matcher.find()) {
            String match = matcher.group(1);
            matcher.appendReplacement(buffer, ChatColor.of(match).toString());
        }
        return matcher.appendTail(buffer).toString();
    }

    @Override
    public boolean tame(Entity entity, Player tamer) {
        if (entity instanceof Fox) {
            if (tamer == null) return false;
            Fox fox = (Fox)entity;
            AnimalTamer current = fox.getFirstTrustedPlayer();
            if (current != null && current.getUniqueId().equals(tamer.getUniqueId())) {
                return false;
            }
            fox.setFirstTrustedPlayer(tamer);
        }
        return super.tame(entity, tamer);
    }

    @Override
    public Recipe createSmithingRecipe(String key, ItemStack item, ItemStack source, ItemStack addition) {
        NamespacedKey namespacedKey = new NamespacedKey(platform.getPlugin(), key);
        if (item == null || source == null) {
            return null;
        }
        try {
            RecipeChoice choice = new RecipeChoice.ExactChoice(source);
            RecipeChoice additionChoice = new RecipeChoice.ExactChoice(addition);
            return new SmithingRecipe(namespacedKey, item, choice, additionChoice);
        } catch (Throwable ex) {
            platform.getLogger().log(Level.SEVERE, "Error creating smithing recipe", ex);
        }
        return null;
    }
}

@@ -1258,32 +1258,90 @@
  ArrayList%3C%3E();%0A
+        List%3CBaseComponent%3E addToComponents = components;%0A
         String%5B%5D
@@ -1375,24 +1375,69 @@
 tainsJson);%0A
+        BaseComponent addToComponent = null;%0A
         for 
@@ -1462,24 +1462,46 @@
 : pieces) %7B%0A
+            try %7B%0A    
             
@@ -1515,34 +1515,32 @@
 seComponent%3E add
-To
 Components = com
@@ -1529,39 +1529,30 @@
 ddComponents
- = components;%0A
+;%0A    
             
@@ -1555,17 +1555,16 @@
     if (
-!
 componen
@@ -1568,18 +1568,23 @@
 nent
-s.isEmpty(
+.startsWith(%22%7B%22
 )) %7B
@@ -1600,35 +1600,23 @@
         
+   
-BaseComponent
  add
-To
 Componen
@@ -1620,53 +1620,90 @@
 nent
+s
  = 
-components.get(components.size() - 1
+Arrays.asList(ComponentSerializer.parse(component)
 );%0A   
+  
+           %7D else %7B%0A
     
@@ -1703,37 +1703,42 @@
  %7B%0A             
+       
 add
-To
 Components = add
@@ -1738,35 +1738,82 @@
 s = 
-addToComponent.getExtra(
+Arrays.asList(TextComponent.fromLegacyText(component)
 );%0A
+                %7D%0A
     
@@ -1828,21 +1828,20 @@
     if (
+!
 add
-To
 Componen
@@ -1842,24 +1842,26 @@
 mponents
- == null
+.isEmpty()
 ) %7B%0A    
@@ -1895,48 +1895,87 @@
 ents
- = new ArrayList%3C%3E();%0A                %7D%0A
+.addAll(addComponents);%0A                    if (addToComponent != null) %7B%0A     
     
@@ -1978,32 +1978,35 @@
                 
+   
 addToComponent.s
@@ -2039,34 +2039,32 @@
             
-%7D%0A
         
     try %7B%0A  
@@ -2047,34 +2047,32 @@
             
+%7D%0A%0A
     
-try %7B%0A
+ 
             
@@ -2078,263 +2078,272 @@
     
- if (component.startsWith(%22%7B%22)) %7B%0A                    addToComponents.addAll(Arrays.asList(ComponentSerializer.parse(component)));%0A                %7D else %7B%0A                    addToComponents.addAll(Arrays.asList(TextComponent.fromLegacyText(component)));
+addToComponent = addToComponents.get(addToComponents.size() - 1);%0A                    addToComponents = addToComponent.getExtra();%0A                    if (addToComponents == null) %7B%0A                        addToComponents = new ArrayList%3C%3E();%0A                    %7D
 %0A   

Fix nesting of combo json/legacy string output