package com.avairebot.orion.commands.utility;

import com.avairebot.orion.Orion;
import com.avairebot.orion.contracts.commands.Command;
import com.avairebot.orion.factories.MessageFactory;
import com.udojava.evalex.Expression;
import net.dv8tion.jda.core.entities.Message;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

public class CalculateCommand extends Command {

    private static final Pattern NUMBER_REGEX = Pattern.compile("^\\d+$");

    public CalculateCommand(Orion orion) {
        super(orion);
    }

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

    @Override
    public String getDescription() {
        return "Calculates the given math equations and returns the result for you.";
    }

    @Override
    public List<String> getUsageInstructions() {
        return Collections.singletonList("`:command <equation>` - Calculates the result of the given math equation.");
    }

    @Override
    public String getExampleUsage() {
        return "`:command (-50 + sqrt(50 ^ 2 - ((4 * 5) * (100 - 955)))) / (2 * 5) == 9`";
    }

    @Override
    public List<String> getTriggers() {
        return Arrays.asList("calculate", "calc");
    }

    @Override
    public boolean onCommand(Message message, String[] args) {
        if (args.length == 0) {
            return sendErrorMessage(message, "Missing argument, the `equation` argument is required!");
        }

        String string = String.join(" ", args).trim();
        if (NUMBER_REGEX.matcher(string).find()) {
            MessageFactory.makeInfo(message, string).queue();
            return true;
        }

        try {
            Expression expression = createExpression(string);
            BigDecimal result = expression.eval();

            System.out.println(expression.getExpression());
            if (expression.isBoolean()) {

                MessageFactory.makeInfo(message, result.intValueExact() == 1
                    ? "True" : "False"
                ).queue();
                return true;
            }

            MessageFactory.makeInfo(message, result.toPlainString()).queue();
        } catch (Exception ex) {
            return sendErrorMessage(message, ex.getMessage().replaceAll("'", "`"));
        }
        return true;
    }

    private Expression createExpression(String string) {
        return new Expression(string)
            .setVariable("tau", new BigDecimal(Math.PI * 2));
    }
}

@@ -2418,24 +2418,115 @@
 g string) %7B%0A
+        int where = string.toLowerCase().indexOf(%22where%22);%0A%0A        if (where == -1) %7B%0A    
         retu
@@ -2551,16 +2551,20 @@
 string)%0A
+    
         
@@ -2613,20 +2613,635 @@
 h.PI * 2));%0A
+        %7D%0A%0A        Expression expression = new Expression(string.substring(0, where).trim())%0A            .setVariable(%22tau%22, new BigDecimal(Math.PI * 2));%0A%0A        for (String var : string.substring(where + 5, string.length()).trim().split(%22 and %22)) %7B%0A            String%5B%5D varArgs = var.split(%22=%22);%0A            if (varArgs.length != 2) %7B%0A                varArgs = var.split(%22is%22);%0A                if (varArgs.length != 2) %7B%0A                    continue;%0A                %7D%0A            %7D%0A%0A            expression.setVariable(varArgs%5B0%5D.trim(), new BigDecimal(varArgs%5B1%5D.trim()));%0A        %7D%0A%0A        return expression;%0A
     %7D%0A%7D%0A

Add support for variables in the calculate command