package me.deftware.client.framework.command.types;

import com.google.common.collect.Lists;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import me.deftware.client.framework.chat.ChatMessage;
import me.deftware.client.framework.chat.LiteralChatMessage;
import me.deftware.client.framework.chat.builder.ChatBuilder;
import me.deftware.client.framework.chat.event.ChatClickEvent;
import me.deftware.client.framework.chat.hud.ChatHud;
import me.deftware.client.framework.chat.hud.ChatHudLine;
import me.deftware.client.framework.chat.style.ChatColors;
import me.deftware.client.framework.command.CommandBuilder;
import me.deftware.client.framework.command.CommandRegister;
import me.deftware.client.framework.command.CommandResult;
import me.deftware.client.framework.command.EMCModCommand;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Deftware
 */
public abstract class AbstractPagedOutputCommand extends EMCModCommand {

    protected final ChatMessage title;
    protected final String command;
    protected int chunkSize = 6;

    public AbstractPagedOutputCommand(String command, ChatMessage title) {
        this.command = command;
        this.title = title;
    }

    public abstract List<ChatMessage> list();

    public List<List<ChatMessage>> getChunks() {
        return Lists.partition(list(), chunkSize);
    }

    @Override
    public CommandBuilder<?> getCommandBuilder() {
        return new CommandBuilder<>().set(LiteralArgumentBuilder.literal(command)
                .then(
                        RequiredArgumentBuilder.argument("page", IntegerArgumentType.integer(-1))
                                .executes(c ->
                                        onExecute(new CommandResult(c).getInteger("page"))
                                )
                )
                .executes(c -> onExecute(0))
        );
    }

    private final List<ChatMessage> previousOuput = new ArrayList<>();

    protected void removePreviousOutput() {
        List<ChatHudLine> removalQueue = new ArrayList<>();
        for (ChatHudLine line : ChatHud.getLines()) {
            for (ChatMessage message : previousOuput) {
                if (line.getMessage().toString(false).equalsIgnoreCase(message.toString(false))) {
                    removalQueue.add(line);
                }
            }
        }
        removalQueue.forEach(ChatHud::remove);
        previousOuput.clear();
    }

    protected void print(ChatMessage message) {
        previousOuput.add(message);
        message.print();
    }

    protected int onExecute(int page) {
        String prefix = CommandRegister.getCommandTrigger();

        // Remove old output
        if (!previousOuput.isEmpty()) {
            removePreviousOutput();
        }

       if (list().isEmpty()) {
           print(new ChatBuilder().withMessage(title).build());
           print(new LiteralChatMessage("Nothing added", ChatColors.GRAY));
       } else {
           // Get chunk
           List<List<ChatMessage>> chunks = getChunks();
           if (page < 0) page = 0;
           if (page == chunks.size()) page = chunks.size() - 1;
           List<ChatMessage> chunk = chunks.get(page);

           // Send title
           print(new ChatBuilder().withMessage(title).withSpace()
                   .withText(String.format("Page (%s/%s)", page + 1, chunks.size())).withColor(ChatColors.AQUA)
                   .build());

           // Send chunk
           chunk.forEach(this::print);

           if (chunks.size() > 1) {
               // Send navigation buttons
               ChatBuilder navigationButtons = new ChatBuilder();
               navigationButtons.withText("<<").withColor(ChatColors.AQUA).withClickEvent(
                       new ChatClickEvent(ChatClickEvent.EventType.RUN_COMMAND, String.format("%s%s %s", prefix, command, page - 1))
               ).withHover("Previous page").append().withSpace();
               navigationButtons.withText(">>").withColor(ChatColors.AQUA).withClickEvent(
                       new ChatClickEvent(ChatClickEvent.EventType.RUN_COMMAND, String.format("%s%s %s", prefix, command, page + 1))
               ).withHover("Next page").append();
               print(navigationButtons.build());
           }
       }

        return 1;
    }

}

@@ -1739,17 +1739,16 @@
 integer(
--
 1))%0A    
@@ -1879,16 +1879,20 @@
 (%22page%22)
+ - 1
 )%0A      
@@ -3213,17 +3213,17 @@
 f (page 
-=
+%3E
 = chunks
@@ -3762,32 +3762,46 @@
 ;%0A              
+ if (page %3E 0)
  navigationButto
@@ -3987,20 +3987,16 @@
 nd, page
- - 1
 ))%0A     
@@ -4070,16 +4070,46 @@
         
+ if (page + 1 %3C chunks.size())
  navigat
@@ -4306,17 +4306,17 @@
  page + 
-1
+2
 ))%0A     

fix page numbering