package de.viper.survivalplus.commands;

import de.viper.survivalplus.SurvivalPlus;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;

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

public class PluginCommand implements CommandExecutor {
    private final SurvivalPlus plugin;
    private static final int COMMANDS_PER_PAGE = 5;

    public PluginCommand(SurvivalPlus plugin) {
        this.plugin = plugin;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        FileConfiguration lang = plugin.getLangConfig();

        // /sp oder /sp help
        if (args.length == 0 || args[0].equalsIgnoreCase("help")) {
            String mode = "all";
            int page = 1;

            if (args.length > 1 && args[0].equalsIgnoreCase("help")) {
                String arg1 = args[1];
                if (isInteger(arg1)) {
                    page = Integer.parseInt(arg1);
                } else {
                    mode = arg1.toLowerCase();
                    if (args.length > 2) {
                        String arg2 = args[2];
                        if (isInteger(arg2)) {
                            page = Integer.parseInt(arg2);
                        } else {
                            sender.sendMessage(color(lang.getString(
                                    "sp.invalid-subcommand",
                                    "§cUngültiger Unterbefehl! Verwendung: /sp help [player|admin|system|all] [seite]"
                            )));
                            return true;
                        }
                    }
                }
            }

            if (page < 1) page = 1;
            showHelp(sender, mode, page);
            return true;
        }

        // /sp reload
        if (args[0].equalsIgnoreCase("reload")) {
            if (!sender.hasPermission("survivalplus.reload")) {
                sender.sendMessage(color(lang.getString("sp.no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")));
                return true;
            }
            plugin.reloadPlugin();
            sender.sendMessage(color(lang.getString("sp.plugin.reloaded", "§aSurvivalPlus wurde erfolgreich neu geladen!")));
            return true;
        }

        // /sp info
        if (args[0].equalsIgnoreCase("info")) {
            sender.sendMessage(color(lang.getString("sp.info.header", "&7===== SurvivalPlus Info =====")));
            sender.sendMessage(color(lang.getString("sp.info.name", "&ePlugin-Name: &f") + plugin.getDescription().getName()));
            sender.sendMessage(color(lang.getString("sp.info.version", "&eVersion: &f") + plugin.getDescription().getVersion()));
            sender.sendMessage(color(lang.getString("sp.info.author", "&eErsteller: &f") + "M_Viper"));
            sender.sendMessage(color(lang.getString("sp.info.description", "&eBeschreibung:\n&f") + plugin.getDescription().getDescription()));

            if (sender instanceof Player player) {
                // Überschrift über die Links
                player.sendMessage(ChatColor.GOLD + "Links:");

                // Button: Spigot-Seite
                TextComponent spigotLink = new TextComponent(ChatColor.GREEN + "[Spigot-Seite]");
                spigotLink.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL,
                        "https://www.spigotmc.org/resources/authors/m-lukas-17.618600/"));
                spigotLink.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                        new ComponentBuilder(ChatColor.YELLOW + "Klicke, um die Spigot-Seite zu öffnen").create()
                ));

                // Button: Bugs melden (Git)
                TextComponent gitLink = new TextComponent(ChatColor.GREEN + " [Bugs melden]");
                gitLink.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL,
                        "https://git.viper.ipv64.net/M_Viper/Survival-Plus/issues"));
                gitLink.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                        new ComponentBuilder(ChatColor.YELLOW + "Klicke, um den Bug-Tracker zu öffnen").create()
                ));

                // Beide nebeneinander
                spigotLink.addExtra(gitLink);
                player.spigot().sendMessage(spigotLink);

            } else {
                sender.sendMessage(ChatColor.GOLD + "Links:");
                sender.sendMessage(ChatColor.GREEN + "[Spigot-Seite] "
                        + "https://www.spigotmc.org/resources/authors/m-lukas-17.618600/"
                        + ChatColor.GREEN + " [Bugs melden] "
                        + "https://git.viper.ipv64.net/M_Viper/Survival-Plus/issues");
            }

            sender.sendMessage(color(lang.getString("sp.info.footer", "&7==========================")));
            return true;
        }

        // /sp share → Vorschau mit Buttons
        if (args[0].equalsIgnoreCase("share")) {
            if (!(sender instanceof Player player)) {
                sender.sendMessage(color(lang.getString("player-only", "§cDieser Befehl ist nur für Spieler!")));
                return true;
            }

            org.bukkit.Location loc = player.getLocation();
            String coordsMsg = color(lang.getString("sp.share.preview-format", "")
                    .replace("%player%", player.getName())
                    .replace("%x%", String.valueOf(loc.getBlockX()))
                    .replace("%y%", String.valueOf(loc.getBlockY()))
                    .replace("%z%", String.valueOf(loc.getBlockZ()))
                    .replace("%world%", loc.getWorld().getName())
            );

            player.sendMessage(color(lang.getString("sp.share.preview-title", "§aDeine aktuellen Koordinaten wären:")));
            player.sendMessage(coordsMsg);

            TextComponent sendBtn = new TextComponent(color(lang.getString("sp.share.send-button", "§a[✅ Senden]")));
            sendBtn.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/sp shareconfirm"));
            sendBtn.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                    new ComponentBuilder(color(lang.getString("sp.share.send-hover",
                            "§aKlicke, um deine Koordinaten an alle zu senden."))).create()
            ));

            TextComponent cancelBtn = new TextComponent(color(lang.getString("sp.share.cancel-button", "§c [❌ Abbrechen]")));
            cancelBtn.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/sp sharecancel"));
            cancelBtn.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                    new ComponentBuilder(color(lang.getString("sp.share.cancel-hover",
                            "§cKlicke, um das Senden abzubrechen."))).create()
            ));

            sendBtn.addExtra(cancelBtn);
            player.spigot().sendMessage(sendBtn);
            return true;
        }

        // /sp shareconfirm → bestätigt und sendet
        if (args[0].equalsIgnoreCase("shareconfirm")) {
            if (!(sender instanceof Player player)) {
                sender.sendMessage(color(lang.getString("player-only", "§cDieser Befehl ist nur für Spieler!")));
                return true;
            }
            org.bukkit.Location loc = player.getLocation();
            String message = color(lang.getString("sp.share.preview-format", "")
                    .replace("%player%", player.getName())
                    .replace("%x%", String.valueOf(loc.getBlockX()))
                    .replace("%y%", String.valueOf(loc.getBlockY()))
                    .replace("%z%", String.valueOf(loc.getBlockZ()))
                    .replace("%world%", loc.getWorld().getName())
            );
            Bukkit.broadcastMessage(message);
            player.sendMessage(color(lang.getString("sp.share.sent", "§aKoordinaten gesendet.")));
            return true;
        }

        // /sp sharecancel → bricht ab
        if (args[0].equalsIgnoreCase("sharecancel")) {
            if (sender instanceof Player p) {
                p.sendMessage(color(lang.getString("sp.share.cancelled", "§eSenden der Koordinaten abgebrochen.")));
            }
            return true;
        }

        // Ungültiger Unterbefehl
        sender.sendMessage(color(lang.getString(
                "sp.invalid-subcommand",
                "§cUngültiger Unterbefehl! Verwendung: /sp [reload|help|info|share]"
        )));
        return true;
    }

    private void showHelp(CommandSender sender, String mode, int page) {
        FileConfiguration help = plugin.getHelpConfig();
        FileConfiguration lang = plugin.getLangConfig();

        if (help == null || help.getConfigurationSection("commands") == null) {
            sender.sendMessage(color(lang.getString("sp.help-not-found", "&cHilfedatei (help.yml) konnte nicht geladen werden!")));
            return;
        }

        List<String> orderedCommands = new ArrayList<>(help.getConfigurationSection("commands").getKeys(false));
        if (orderedCommands.isEmpty()) {
            sender.sendMessage(color(lang.getString("sp.help-not-found", "&cKeine Befehle verfügbar.")));
            return;
        }

        String normalizedMode = mode == null ? "all" : mode.toLowerCase();
        if (!normalizedMode.equals("all") && !normalizedMode.equals("player")
                && !normalizedMode.equals("admin") && !normalizedMode.equals("system")) {
            sender.sendMessage(color(help.getString(
                    "help-usage",
                    "&cVerwendung: /sp help [player|admin|system|all] [seite]"
            )));
            return;
        }

        List<String> commands = new ArrayList<>();
        for (String key : orderedCommands) {
            String group = help.getString("commands." + key + ".group", "player").toLowerCase();
            if (normalizedMode.equals("all") || group.equals(normalizedMode)) {
                commands.add(key);
            }
        }

        if (commands.isEmpty()) {
            sender.sendMessage(color(lang.getString("sp.help-not-found", "&cKeine Befehle verfügbar.")));
            return;
        }

        int totalPages = (int) Math.ceil((double) commands.size() / COMMANDS_PER_PAGE);
        if (page > totalPages) page = totalPages;
        if (page < 1) page = 1;

        sender.sendMessage(color(help.getString("header", "&7===== &eSurvivalPlus Hilfe &7=====")));

        int startIndex = (page - 1) * COMMANDS_PER_PAGE;
        int endIndex = Math.min(startIndex + COMMANDS_PER_PAGE, commands.size());

        String lastGroup = null;
        for (int i = startIndex; i < endIndex; i++) {
            String cmd = commands.get(i);
            String group = help.getString("commands." + cmd + ".group", "player").toLowerCase();
            if (lastGroup == null || !lastGroup.equals(group)) {
                String groupTitle = help.getString("groups." + group + ".title", "&6-- " + group + " --");
                sender.sendMessage(color(groupTitle));
                lastGroup = group;
            }
            String usage = help.getString("commands." + cmd + ".usage", "");
            String description = help.getString("commands." + cmd + ".description", "");
            sender.sendMessage(color(usage + " §7- " + description));
        }

        if (sender instanceof Player player) {
            String modeSuffix = normalizedMode.equals("all") ? "" : " " + normalizedMode;
            String navBase = "/sp help" + modeSuffix + " ";
            TextComponent navigation = new TextComponent();

            if (page > 1) {
                TextComponent prev = new TextComponent(color(help.getString("navigation.prev", "« Vorherige ")));
                prev.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, navBase + (page - 1)));
                prev.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                        new ComponentBuilder("§7Klicke für Seite " + (page - 1)).create()));
                navigation.addExtra(prev);
            } else {
                navigation.addExtra(color(help.getString("navigation.prev-disabled", "« ")));
            }

            TextComponent pageInfo = new TextComponent(color(help.getString("navigation.page", " §fSeite {current} von {total} "))
                    .replace("{current}", String.valueOf(page))
                    .replace("{total}", String.valueOf(totalPages)));
            navigation.addExtra(pageInfo);

            if (page < totalPages) {
                TextComponent next = new TextComponent(color(help.getString("navigation.next", " Nächste »")));
                next.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, navBase + (page + 1)));
                next.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                        new ComponentBuilder("§7Klicke für Seite " + (page + 1)).create()));
                navigation.addExtra(next);
            } else {
                navigation.addExtra(color(help.getString("navigation.next-disabled", " »")));
            }

            player.spigot().sendMessage(navigation);
        } else {
            for (String cmd : commands) {
                String usage = help.getString("commands." + cmd + ".usage", "");
                String description = help.getString("commands." + cmd + ".description", "");
                sender.sendMessage(color(usage + " §7- " + description));
            }
        }

        sender.sendMessage(color(help.getString("footer", "&7==========================")));
    }

    private boolean isInteger(String value) {
        if (value == null || value.isEmpty()) {
            return false;
        }
        for (int i = 0; i < value.length(); i++) {
            if (!Character.isDigit(value.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    private String color(String input) {
        return ChatColor.translateAlternateColorCodes('&', input == null ? "" : input);
    }
}
