// Format a number as USD currency.
// If `showChangeIfExists` is false, the cents value is only shown if there are leftover cents
// after converting to dollars (i.e. amount=1000 would be shown as $10, but amount=1001 would be
// shown as $10.01). If true, cents are always displayed.
export function formatCurrency(amount: number, showChangeIfExists: boolean = true): string {
    const dollars = amount / 100;
    return new Intl.NumberFormat("en-US", {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
        trailingZeroDisplay: (showChangeIfExists ? "auto" : "stripIfInteger"),
        useGrouping: false,
    }).format(dollars);
}

// // Same as formatMoney() but with commas.
export function formatCurrencyWithCommas(amount: number, showChangeIfExists: boolean = true): string {
    const dollars = amount / 100;
    return new Intl.NumberFormat("en-US", {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
        trailingZeroDisplay: (showChangeIfExists ? "auto" : "stripIfInteger"),
    }).format(dollars);
}

// takes a number such as 123456, and outputs (1234, 56) as strings
export function splitCurrency(amount: number): [string, string] {
    // Calculate dollars as a string (without cents)
    const dollars = Math.floor(amount / 100).toString();
    // Calculate cents as a string with leading zero if necessary;
    const cents = (amount % 100).toString().padStart(2, "0");
    return [dollars, cents];
}

export function moneyToNumber(input: string): number {
    if (!input.includes(".")) {
        input += ".00";
    } else if (input.split(".").length - 1 === 1) {
        const digits = input.split(".");
        if (digits[1].length === 1) {
            input += "0";
        }
    }
    let processed = input
        .replaceAll(".", "")
        .replaceAll(",", "")
        .replaceAll(" ", "");
    return parseInt(processed);
}

export function formatRate(rate: number): string {
    return (rate / 1000).toFixed(3);
}

export function processDiscount(discount: string): number {
    const discountFloat = parseFloat(discount);

    if (discountFloat < 0) {
        return 0;
    } else if (discountFloat > 100) {
        return 100;
    }

    return discountFloat;
}

// Takes days as an input and outputs the string representation of the number
// of days, months, or years in the term based on which unit is the best fit
// for the amount of days along with the corresponding unit string.
export function daysToRateTerm(days: number): [string, string] {
    const years = Math.floor(days / 365);
    const months = Math.floor((days - years*365) / 30);
    const dayRemainder = days - years*365 - months*30;

    if (days == 0) { // Return empty string for value
        return ["", "days"];
    } else if (days <= 270 || dayRemainder > 0) {
        return [days.toString(), "days"]
    } else if (months > 0) {
        return [(months + years*12).toString(), "months"];
    } else {
        return [years.toString(), "years"];
    }
}

export function rateTermToDays(value: string, unit: string): number {
    const valueNum = parseInt(value);

    switch (unit) {
        case "months":
            const years = Math.floor(valueNum / 12);
            const months = valueNum % 12;
            return years*365 + months*30;
        case "years":
            return valueNum * 365;
        default: // case "days":
            return valueNum;
    }
}