package net.knarcraft.blacksmith.command;

import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.knarcraft.blacksmith.config.NPCSetting;
import net.knarcraft.blacksmith.manager.Message;
import net.knarcraft.blacksmith.trait.BlacksmithTrait;
import net.knarcraft.blacksmith.util.MessageFormatter;
import net.knarcraft.blacksmith.util.TypeValidationHelper;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;

import static net.knarcraft.blacksmith.util.MessageFormatter.displaySuccessMessage;

/**
 * The main command used for blacksmith editing
 */
public class BlackSmithEditCommand implements CommandExecutor {

    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
                             @NotNull String[] args) {
        NPC npc = CitizensAPI.getDefaultNPCSelector().getSelected(sender);
        if (npc == null || !npc.hasTrait(BlacksmithTrait.class)) {
            MessageFormatter.displayErrorMessage(sender, "You must select an NPC before running this command");
            return true;
        }

        if (args.length < 1) {
            return false;
        }

        BlacksmithTrait blacksmithTrait = npc.getTrait(BlacksmithTrait.class);

        for (NPCSetting npcSetting : NPCSetting.values()) {
            String commandName = npcSetting.getCommandName();
            if (commandName.equalsIgnoreCase(args[0])) {
                String newValue = args.length < 2 ? null : args[1];
                return changeNPCSetting(blacksmithTrait, npcSetting, newValue, sender);
            }
        }
        return false;
    }

    /**
     * Changes the given NPC setting, or displays the current value if a new value isn't specified
     *
     * @param blacksmithTrait <p>The blacksmith trait belonging to the selected NPC</p>
     * @param npcSetting      <p>The NPC setting to change</p>
     * @param newValue        <p>The value to change the setting to</p>
     * @param sender          <p>The command sender to notify about results</p>
     * @return <p>True if everything went successfully</p>
     */
    private boolean changeNPCSetting(BlacksmithTrait blacksmithTrait, NPCSetting npcSetting, String newValue,
                                     CommandSender sender) {
        if (newValue == null) {
            //Display the current value of the setting
            String rawValue = String.valueOf(blacksmithTrait.getSettings().getRawValue(npcSetting));
            displaySuccessMessage(sender, Message.getCurrentValueMessage(npcSetting.getCommandName(), rawValue));
            sender.sendMessage("Raw value: " + rawValue.replace(ChatColor.COLOR_CHAR, '&'));
            return true;
        } else {
            boolean isValidType = TypeValidationHelper.isValid(npcSetting.getValueType(), newValue, sender);
            if (isValidType) {
                //Change the setting
                blacksmithTrait.getSettings().changeSetting(npcSetting,
                        ChatColor.translateAlternateColorCodes('&', newValue));
                displaySuccessMessage(sender, Message.getValueChangedMessage(npcSetting.getNodeName(), newValue));
                return true;
            } else {
                return false;
            }
        }
    }

}
