"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NumberFormatter = NumberFormatter;
exports.DateFormatter = DateFormatter;
exports.StringFormatter = StringFormatter;
const tslib_1 = require("tslib");
// TODO inspect why the following is erroring on angular build
const date_fns_1 = require("date-fns");
const sentenceCase_1 = tslib_1.__importDefault(require("../utils/sentenceCase"));
const GeneralConstants_1 = require("../Constants/GeneralConstants");
const Helper_1 = tslib_1.__importDefault(require("./Helper"));
const StringExtensions_1 = tslib_1.__importDefault(require("../Extensions/StringExtensions"));
function NumberFormatter(input, options = {}, rowNode, column, api) {
    let preparedInput;
    if (options.Content) {
        const context = {
            column,
            rowNode,
            input,
            api,
        };
        preparedInput = formatPlaceholder(options.Content.toString(), context);
    }
    else {
        preparedInput = input;
    }
    if (preparedInput == null || preparedInput == undefined) {
        return undefined;
    }
    if (typeof preparedInput === 'string') {
        return preparedInput;
    }
    let n = Number(preparedInput);
    if (isNaN(n)) {
        return preparedInput.toString();
    }
    let multiplier = options.Multiplier ? options.Multiplier : 1;
    if (options.Multiplier !== undefined) {
        n *= multiplier;
        n = parseFloat(n.toFixed(12));
    }
    // Set Integer and Fraction Digits to a max of 20
    if (options.IntegerDigits > 20) {
        options.IntegerDigits = 20;
    }
    if (options.FractionDigits > 20) {
        options.FractionDigits = 20;
    }
    if (options.Parentheses === true && preparedInput < 0) {
        n *= -1;
        n = parseFloat(n.toFixed(12));
    }
    if (options.Abs) {
        n = Math.abs(n);
    }
    if (options.Truncate) {
        n = Math.trunc(n);
    }
    if (options.Ceiling) {
        n = Math.ceil(n);
    }
    if (options.Round) {
        n = Math.round(n);
    }
    if (options.Floor) {
        n = Math.floor(n);
    }
    if (options.Empty) {
        return ' ';
    }
    let s;
    let digitsToUse;
    const fractionsSepatator = options.FractionSeparator ?? '.';
    if (options.Truncate || options.Ceiling || options.Round || options.Floor) {
        digitsToUse = 0;
    }
    else if (options.FractionDigits != null) {
        digitsToUse = options.FractionDigits;
    }
    else {
        let decimalCount = Math.floor(n) === n ? 0 : n.toString().split(fractionsSepatator)[1]?.length || 0;
        digitsToUse = decimalCount;
    }
    s = n.toLocaleString('en-US', {
        minimumIntegerDigits: options.IntegerDigits || undefined,
        minimumFractionDigits: digitsToUse,
        maximumFractionDigits: digitsToUse,
    });
    if (options.FractionSeparator !== undefined) {
        s = s.replace(/\./g, options.FractionSeparator);
    }
    if (options.IntegerSeparator !== undefined) {
        // if fraction separator is not a comma then simply replace all instances
        if (options.FractionSeparator !== ',') {
            s = s.replace(/\,/g, options.IntegerSeparator);
        }
        else {
            // otherwise don't replace the last instance
            s = StringExtensions_1.default.ReplaceAllOccurencesExceptLastOne(s, ',', options.IntegerSeparator);
        }
    }
    s = (options.Prefix || '') + s + (options.Suffix || '');
    if (options.Parentheses === true && preparedInput < 0) {
        s = '(' + s + ')';
    }
    return s;
}
function DateFormatter(input, options, strictFormatting = false) {
    if (input == null || input == undefined || input == 'Invalid Date') {
        return undefined;
    }
    try {
        if (typeof input === 'string') {
            // Remove timezone info (e.g., Z or +02:00) using regex
            const cleanDateString = input.replace(/([+-]\d{2}:\d{2}|Z)$/, '');
            input = new Date(cleanDateString);
        }
        return (0, date_fns_1.format)(input, options?.Pattern || GeneralConstants_1.DEFAULT_DATE_FORMAT_PATTERN);
    }
    catch (error) {
        if (strictFormatting) {
            return `Invalid date formatting pattern`;
        }
        if (typeof input !== 'string') {
            return String(input);
        }
        return input;
    }
}
function StringFormatter(input, options = {}, rowNode, column, api) {
    let normalisedTextInput = input;
    if (input != undefined && typeof input !== 'string') {
        const warningMessage = column
            ? `StringFormatter: input '${input}' from column ${column.columnId} (${column.dataType}) is not a string, but a ${typeof input}`
            : `StringFormatter: input '${input}' is not a string, received ${typeof input}`;
        if (api) {
            api.logWarn(warningMessage);
        }
        else {
            console.warn(warningMessage);
        }
        normalisedTextInput = `${input}`;
    }
    let preparedInput;
    if (options.Content) {
        const context = {
            column,
            rowNode,
            input: normalisedTextInput,
            api,
        };
        preparedInput = formatPlaceholder(options.Content, context);
    }
    else {
        preparedInput = normalisedTextInput;
    }
    if (StringExtensions_1.default.IsNullOrEmptyOrWhiteSpace(preparedInput)) {
        return undefined;
    }
    if (options.Empty) {
        return ' ';
    }
    let s = preparedInput;
    if (options.Prefix !== undefined) {
        s = options.Prefix + s;
    }
    if (options.Suffix !== undefined) {
        s = s + options.Suffix;
    }
    if (options.Case !== undefined) {
        if (options.Case == 'Lower') {
            s = s.toLowerCase();
        }
        else if (options.Case == 'Upper') {
            s = s.toUpperCase();
        }
        else if (options.Case == 'Sentence') {
            s = (0, sentenceCase_1.default)(s);
        }
    }
    if (options.Trim !== undefined && options.Trim == true) {
        s = s.trim();
    }
    return s;
}
function formatPlaceholder(text, context) {
    if (!text) {
        return text;
    }
    if (!context) {
        return text;
    }
    if (context?.input) {
        text = Helper_1.default.replaceAll(text, '[value]', context.input);
    }
    if (context?.column) {
        text = Helper_1.default.replaceAll(text, '[column]', context.api.columnApi.getFriendlyNameForColumnId(context.column.columnId));
    }
    if (context?.rowNode) {
        const columns = Helper_1.default.extractColsFromText(text);
        for (const column of columns) {
            if (context.api.columnApi.getColumnWithColumnId(column)) {
                text = Helper_1.default.replaceAll(text, `[rowData.${column}]`, context.api.gridApi.getRawValueFromRowNode(context.rowNode, column));
            }
        }
    }
    return text;
}
exports.default = { NumberFormatter, DateFormatter, StringFormatter };
