package com.leonardobishop.quests.quests.tasktypes.types;

import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.quests.Task;
import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
import com.leonardobishop.quests.quests.tasktypes.TaskTypeManager;
import org.bukkit.event.EventHandler;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.BentoBoxEvent;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

public final class BentoBoxLevelTaskType extends TaskType {

    private List<ConfigValue> creatorConfigValues = new ArrayList<>();
    private Field levelField = null;

    public BentoBoxLevelTaskType() {
        super("bentobox_level", "Rodney_Mc_Kay", "Reach a certain island level in the level addon for BentoBox.");
        this.creatorConfigValues.add(new ConfigValue("level", true, "Minimum island level needed."));
    }

    @Override
    public List<ConfigValue> getCreatorConfigValues() {
        return creatorConfigValues;
    }

    public static void register(TaskTypeManager manager) {
        if (BentoBox.getInstance().getAddonsManager().getAddonByName("Level").isPresent()) {
            manager.registerTaskType(new BentoBoxLevelTaskType());
        }
    }

    @EventHandler
    public void onBentoBoxIslandLevelCalculated(BentoBoxEvent event) {
        if ("IslandLevelCalculatedEvent".equalsIgnoreCase(event.getEventName())) {
            QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer((UUID) event.getKeyValues().get("targetPlayer"));
            if (qPlayer == null) {
                return;
            }

            QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();

            for (Quest quest : super.getRegisteredQuests()) {
                if (questProgressFile.hasStartedQuest(quest)) {
                    QuestProgress questProgress = questProgressFile.getQuestProgress(quest);

                    for (Task task : quest.getTasksOfType(super.getType())) {
                        TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());

                        if (taskProgress.isCompleted()) {
                            continue;
                        }

                        long islandLevelNeeded = (long) (int) task.getConfigValue("level");

                        Object results = event.getKeyValues().get("results");

                        try {
                            if (levelField == null) {
                                levelField = results.getClass().getDeclaredField("level");
                                levelField.setAccessible(true);
                            }

                            AtomicLong level = (AtomicLong) levelField.get(results);
                            taskProgress.setProgress(level.get());
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            e.printStackTrace();
                        }

                        if (((long) taskProgress.getProgress()) >= islandLevelNeeded) {
                            taskProgress.setCompleted(true);
                        }
                    }
                }
            }
        }
    }
}

@@ -789,16 +789,72 @@
 oxEvent;
+%0Aimport world.bentobox.bentobox.database.objects.Island;
 %0A%0Aimport
@@ -926,24 +926,46 @@
 .util.List;%0A
+import java.util.Map;%0A
 import java.
@@ -1888,24 +1888,87 @@
 nt event) %7B%0A
+        Map%3CString, Object%3E keyValues = event.getKeyValues();%0A%0A
         if (
@@ -2030,32 +2030,161 @@
 EventName())) %7B%0A
+            Island island = (Island) keyValues.get(%22targetPlayer%22);%0A%0A            for (UUID member : island.getMemberSet()) %7B%0A    
             QPla
@@ -2240,58 +2240,21 @@
 yer(
-(UUID) event.getKeyValues().get(%22targetPlayer%22));%0A
+member);%0A    
     
@@ -2300,22 +2300,28 @@
         
-return
+    continue
 ;%0A      
@@ -2318,35 +2318,43 @@
 ue;%0A            
+ 
-%7D%0A%0A
+   %7D%0A%0A    
             Ques
@@ -2428,24 +2428,28 @@
             
+    
 for (Quest q
@@ -2498,24 +2498,28 @@
             
+   
+ 
 if (questPro
@@ -2550,24 +2550,28 @@
 t(quest)) %7B%0A
+    
             
@@ -2668,24 +2668,28 @@
             
+ 
+   
 for (Task ta
@@ -2758,16 +2758,20 @@
         
+  
+  
 TaskProg
@@ -2856,24 +2856,28 @@
             
+    
 if (taskProg
@@ -2894,24 +2894,28 @@
 pleted()) %7B%0A
+    
             
@@ -2956,35 +2956,43 @@
                 
-%7D%0A%0A
+    %7D%0A%0A    
                 
@@ -3092,16 +3092,20 @@
         
+    
 Object r
@@ -3113,34 +3113,25 @@
 sults = 
-event.getK
+k
 eyValues
 ().get(%22
@@ -3122,18 +3122,16 @@
 eyValues
-()
 .get(%22re
@@ -3164,16 +3164,20 @@
         
+    
 try %7B%0A  
@@ -3198,24 +3198,28 @@
             
+  
+  
 if (levelFie
@@ -3224,32 +3224,36 @@
 ield == null) %7B%0A
+    
                 
@@ -3323,24 +3323,28 @@
 d(%22level%22);%0A
+    
             
@@ -3415,35 +3415,43 @@
                 
-%7D%0A%0A
+    %7D%0A%0A    
                 
@@ -3539,32 +3539,36 @@
                 
+   
+ 
 taskProgress.set
@@ -3586,24 +3586,28 @@
 vel.get());%0A
+    
             
@@ -3706,16 +3706,20 @@
         
+    
 e.printS
@@ -3747,35 +3747,43 @@
                 
+ 
-%7D%0A%0A
+   %7D%0A%0A    
                 
@@ -3874,32 +3874,36 @@
                 
+    
 taskProgress.set
@@ -3911,32 +3911,62 @@
 ompleted(true);%0A
+                            %7D%0A
                 

Fix bentobox island members not being included in level task