package net.viper.status.modules.customcommands;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.ChatEvent;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin; // Import f\u00fcr das Interface Argument
import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
import net.md_5.bungee.event.EventHandler;
import net.viper.status.StatusAPI;
import net.viper.status.module.Module;

public class CustomCommandModule implements Module, Listener {

    private StatusAPI plugin;
    private Configuration config;
    private Command chatCommand;

    public CustomCommandModule() {
        // Leerer Konstruktor
    }

    @Override
    public String getName() {
        return "CustomCommandModule";
    }

    @Override
    public void onEnable(Plugin plugin) {
        // Hier casten wir 'Plugin' zu 'StatusAPI', da wir wissen, dass es das ist
        this.plugin = (StatusAPI) plugin;
        
        this.plugin.getLogger().fine("Lade CustomCommandModule...");
        reloadConfig();
        if (this.config == null) {
            this.config = new Configuration();
            this.plugin.getLogger().warning("customcommands.yml konnte nicht geladen werden. Verwende leere Konfiguration.");
        }

        // /bcmds Reload Befehl registrieren
        this.plugin.getProxy().getPluginManager().registerCommand(this.plugin, new Command("bcmds") {
            @Override
            public void execute(CommandSender sender, String[] args) {
                if (!sender.hasPermission("statusapi.bcmds")) {
                    sender.sendMessage(new TextComponent(ChatColor.RED + "You don't have permission."));
                } else {
                    reloadConfig();
                    sender.sendMessage(new TextComponent(ChatColor.GREEN + "Config reloaded."));
                }
            }
        });

        // /chat Befehl registrieren (falls aktiviert)
        if (config.getBoolean("chat-command", true)) {
            chatCommand = new Command("chat") {
                @Override
                public void execute(CommandSender sender, String[] args) {
                    if (sender instanceof ProxiedPlayer) {
                        ProxiedPlayer player = (ProxiedPlayer) sender;
                        if (player.getServer() == null) {
                            player.sendMessage(new TextComponent(ChatColor.RED + "Konnte deinen Server nicht ermitteln. Bitte versuche es erneut."));
                            return;
                        }
                        String msg = String.join(" ", args);
                        if (msg.trim().isEmpty()) {
                            player.sendMessage(new TextComponent(ChatColor.RED + "Bitte gib eine Nachricht an."));
                            return;
                        }
                        ChatEvent e = new ChatEvent(player, player.getServer(), msg);
                        ProxyServer.getInstance().getPluginManager().callEvent(e);
                        if (!e.isCancelled()) {
                            if (!e.isCommand() || !ProxyServer.getInstance().getPluginManager().dispatchCommand(sender, msg.substring(1))) {
                                player.chat(msg);
                            }
                        }
                    } else {
                        String msg = String.join(" ", args);
                        if(msg.startsWith("/")) {
                            ProxyServer.getInstance().getPluginManager().dispatchCommand(sender, msg.substring(1));
                        } else {
                            sender.sendMessage(new TextComponent("Console cannot send chat messages via /chat usually."));
                        }
                    }
                }
            };
            this.plugin.getProxy().getPluginManager().registerCommand(this.plugin, chatCommand);
        }

        this.plugin.getProxy().getPluginManager().registerListener(this.plugin, this);
    }

    @Override
    public void onDisable(Plugin plugin) {
        // Optional: Cleanup logic, falls n\u00f6tig.
        // Wir nutzen hier das \u00fcbergebene 'plugin' Argument (oder this.plugin, ist egal)
        // Listener und Commands werden automatisch entfernt, wenn das Plugin stoppt.
    }

    public void reloadConfig() {
        try {
            if (!this.plugin.getDataFolder().exists()) {
                this.plugin.getDataFolder().mkdirs();
            }
            File file = new File(this.plugin.getDataFolder(), "customcommands.yml");
            if (!file.exists()) {
                // Kopieren aus Resources
                InputStream in = this.plugin.getResourceAsStream("customcommands.yml");
                if (in == null) {
                    this.plugin.getLogger().warning("customcommands.yml nicht in JAR gefunden. Erstelle leere Datei.");
                    file.createNewFile();
                } else {
                    Files.copy(in, file.toPath(), new CopyOption[0]);
                    in.close();
                }
            }
            this.config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(file);
        } catch (IOException e) {
            e.printStackTrace();
            this.plugin.getLogger().severe("Konnte customcommands.yml nicht laden!");
        }
    }

    @EventHandler(priority = 64) 
    public void onCommand(ChatEvent e) {
        if (!e.isCommand()) return;
        if (!(e.getSender() instanceof ProxiedPlayer)) return;

        final ProxiedPlayer player = (ProxiedPlayer) e.getSender();
        String[] split = e.getMessage().split(" ");
        String label = split[0].substring(1);
        
        final List<String> args = new ArrayList<>(Arrays.asList(split));
        args.remove(0);

        Configuration cmds = config.getSection("commands");
        if (cmds == null) return;

        Configuration section = null;
        String foundKey = null;

        for (String key : cmds.getKeys()) {
            Configuration cmdSection = cmds.getSection(key);
            if (key.equalsIgnoreCase(label)) {
                section = cmdSection;
                foundKey = key;
                break;
            }
            for (String alias : cmdSection.getStringList("aliases")) {
                if (alias.equalsIgnoreCase(label)) {
                    section = cmdSection;
                    foundKey = key;
                    break;
                }
            }
            if (section != null) break;
        }

        if (section == null) return;

        String type = section.getString("type", "line");
        String sendertype = section.getString("sender", "default");
        String permission = section.getString("permission", "");
        final List<String> commands = section.getStringList("commands");

        if (!permission.isEmpty() && !player.hasPermission(permission)) {
            player.sendMessage(new TextComponent(ChatColor.RED + "You don't have permission."));
            e.setCancelled(true);
            return;
        }

        e.setCancelled(true);

        final CommandSender target;
        if (sendertype.equals("default")) {
            target = player;
        } else if (sendertype.equals("admin")) {
            target = new ForwardSender(player, true);
        } else if (sendertype.equals("console")) {
            target = ProxyServer.getInstance().getConsole();
        } else {
            ProxiedPlayer targetPlayer = ProxyServer.getInstance().getPlayer(sendertype);
            if (targetPlayer == null || !targetPlayer.isConnected()) {
                player.sendMessage(new TextComponent(ChatColor.RED + "Player " + sendertype + " is not online."));
                return;
            }
            target = targetPlayer;
        }

        String argsString = args.size() >= 1 ? String.join(" ", args) : "";
        final String finalArgs = argsString;
        final String senderName = player.getName();

        if (type.equals("random")) {
            int randomIndex = new Random().nextInt(commands.size());
            String rawCommand = commands.get(randomIndex);
            executeCommand(target, rawCommand, finalArgs, senderName);
        } else if (type.equals("line")) {
            ProxyServer.getInstance().getScheduler().runAsync(this.plugin, new Runnable() {
                @Override
                public void run() {
                    for (String rawCommand : commands) {
                        executeCommand(target, rawCommand, finalArgs, senderName);
                        try {
                            Thread.sleep(100L); 
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            });
        } else {
            this.plugin.getLogger().warning("Unknown type '" + type + "' for command " + foundKey);
        }
    }

    private void executeCommand(CommandSender sender, String rawCommand, String args, String playerName) {
        String parsed = rawCommand
                .replace("%args%", args)
                .replace("%sender%", playerName);

        String commandToDispatch = parsed.startsWith("/") ? parsed.substring(1) : parsed;
        ProxyServer.getInstance().getPluginManager().dispatchCommand(sender, commandToDispatch);
    }
}
