package WowneroChanBot;

import com.litesoftwares.coingecko.CoinGeckoApiClient;
import com.litesoftwares.coingecko.constant.Currency;
import com.litesoftwares.coingecko.impl.CoinGeckoApiClientImpl;

import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

import static WowneroChanBot.Responses.*;

public class Converter {

    private static final CoinGeckoApiClient client = new CoinGeckoApiClientImpl();

    private static final String WOWNERO = "wownero";

    private static final int IS_LESS_THAN_ONE = 0;
    private static final int IS_LESS_THAN_TEN = 1;
    private static final int IS_LESS_THAN_THOUSAND = 2;
    private static final int IS_LESS_THAN_HUNDRED_THOUSAND = 3;

    public static final int  WOW_TO_USD = 1;
    public static final int  USD_TO_WOW = 2;
    public static final int  WOW_TO_BTC = 3;
    public static final int  BTC_TO_WOW = 4;
    public static final int  WOW_TO_XMR = 5;
    public static final int  XMR_TO_WOW = 6;

    private BigDecimal getWowPriceInUsd() {
        return BigDecimal.valueOf(client.getPrice(WOWNERO, Currency.USD).get(WOWNERO).get(Currency.USD));
    }
    public String getWowPriceInUsdAsString(){
        return formatUsdAmountAsString(getWowPriceInUsd());
    }

    private BigDecimal getWowPriceInBtc(){
        return BigDecimal.valueOf(client.getPrice(WOWNERO, Currency.BTC).get(WOWNERO).get(Currency.BTC));
    }
    public String getWowPriceInBtcAsString(){
        return formatBtcAmountAsString(getWowPriceInBtc());
    }

    private BigDecimal getWowPriceInXmr() {
        return BigDecimal.valueOf(client.getPrice(WOWNERO, Currency.USD).get(WOWNERO).get(Currency.USD))
                .divide(BigDecimal.valueOf(client.getPrice("monero", Currency.USD).get("monero").get(Currency.USD)), MathContext.DECIMAL128);
    }



    public String convertWowToUsd(String wowAmountString) {
        try {
            return formatUsdAmountAsString(new BigDecimal(wowAmountString).multiply(getWowPriceInUsd()));
        } catch (NumberFormatException numberFormatException) {
            return WOW_TO_USD_MISSING_AMOUNT_REPLY;
        }
    }
    public String convertUsdToWow(String usdAmountString) {
        try {
            return formatWowAmountAsString(new BigDecimal((usdAmountString)).divide(getWowPriceInUsd(), MathContext.DECIMAL128));
        } catch (NumberFormatException numberFormatException) {
            return USD_TO_WOW_MISSING_AMOUNT_REPLY;
        }
    }

    public String convertBtcToWow(String btcAmountString) {
        try {
            return formatWowAmountAsString(new BigDecimal(btcAmountString).divide(getWowPriceInBtc(), MathContext.DECIMAL128));
        } catch (NumberFormatException numberFormatException) {
            return BTC_TO_WOW_MISSING_AMOUNT_REPLY;
        }
    }
    public String convertWowToBtc(String wowAmountString) {
        try {
            return formatBtcAmountAsString(new BigDecimal(wowAmountString).multiply(getWowPriceInBtc()));
        } catch (NumberFormatException numberFormatException) {
            return WOW_TO_BTC_MISSING_AMOUNT_REPLY;
        }
    }

    public String convertWowToXmr(String wowAmountString) {
        try {
            return formatXmrAmountAsString(new BigDecimal(wowAmountString).multiply(getWowPriceInXmr()));
        } catch (NumberFormatException numberFormatException) {
            return WOW_TO_XMR_MISSING_AMOUNT_REPLY;
        }
    }
    public String convertXmrToWow(String xmrAmountString) {
        try {
            return formatWowAmountAsString(new BigDecimal(xmrAmountString).divide(getWowPriceInXmr(), MathContext.DECIMAL128));
        }
        catch (NumberFormatException numberFormatException) {
            return XMR_TO_WOW_MISSING_AMOUNT_REPLY;
        }
    }

    private String formatWowAmountAsString(BigDecimal wowAmount) {
        boolean[] xmrAmountBoolean = amountBooleanArray(wowAmount);

        if (xmrAmountBoolean[IS_LESS_THAN_ONE]) {
            return new DecimalFormat("#.############").format(wowAmount) + " WOW";
        } else {
            if (xmrAmountBoolean[IS_LESS_THAN_TEN]) {
                return new DecimalFormat("#.###").format(wowAmount) + " WOW";
            } else if (xmrAmountBoolean[IS_LESS_THAN_THOUSAND]) {
                return new DecimalFormat("#.##").format(wowAmount) + " WOW";
            } else {
                NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
                numberFormat.setMaximumFractionDigits(0);

                return numberFormat.format(wowAmount) + " WOW";
            }
        }
    }
    private String formatUsdAmountAsString(BigDecimal usdAmount) {
        return NumberFormat.getCurrencyInstance(Locale.US).format(usdAmount);
    }
    private String formatBtcAmountAsString(BigDecimal btcAmount) {
        boolean[] btcAmountBoolean = amountBooleanArray(btcAmount);

        if (btcAmountBoolean[IS_LESS_THAN_ONE]) {
            return new DecimalFormat("#.############").format(btcAmount) + " BTC";
        } else {
            if (btcAmountBoolean[IS_LESS_THAN_TEN]) {
                return new DecimalFormat("#.#####").format(btcAmount) + " BTC";
            } else if (btcAmountBoolean[IS_LESS_THAN_THOUSAND]) {
                return new DecimalFormat("#.###").format(btcAmount) + " BTC";
            } else {
                NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
                numberFormat.setMaximumFractionDigits(0);

                return numberFormat.format(btcAmount) + " BTC";
            }
        }
    }
    private String formatXmrAmountAsString(BigDecimal xmrAmount) {
        boolean[] btcAmountBoolean = amountBooleanArray(xmrAmount);

        if (btcAmountBoolean[IS_LESS_THAN_ONE]) {
            return new DecimalFormat("#.############").format(xmrAmount) + " XMR";
        } else {
            if (btcAmountBoolean[IS_LESS_THAN_TEN]) {
                return new DecimalFormat("#.#####").format(xmrAmount) + " XMR";
            } else if (btcAmountBoolean[IS_LESS_THAN_THOUSAND]) {
                return new DecimalFormat("#.###").format(xmrAmount) + " XMR";
            } else {
                NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
                numberFormat.setMaximumFractionDigits(0);

                return numberFormat.format(xmrAmount) + " XMR";
            }
        }
    }

    private boolean[] amountBooleanArray(BigDecimal amount) {
        boolean[] amountBooleanArray = {false, false, false};

        if (amount.compareTo(BigDecimal.ONE) <= 0) {
            amountBooleanArray[IS_LESS_THAN_ONE] = true;
        } else if (amount.compareTo(BigDecimal.TEN) < 0) {
            amountBooleanArray[IS_LESS_THAN_TEN] = true;
        } else if (amount.compareTo(BigDecimal.TEN) >= 0 && amount.compareTo(BigDecimal.valueOf(1000)) < 0) {
            amountBooleanArray[IS_LESS_THAN_THOUSAND] = true;
        }

        return amountBooleanArray;
    }
}


