// Fusion Accounting - Report Utility Functions
// Copyright (C) 2026 Nexa Systems Inc.

const LINE_ID_HIERARCHY_DELIMITER = "|";
const LINE_ID_GROUP_DELIMITER = "~";

/**
 * Constructs a hierarchical line identifier string from an array of
 * [markup, model, value] tuples, using delimiters for serialization.
 * @param {Array} current - Array of [markup, model, value] tuples
 * @returns {string} Serialized line ID
 */
export function buildLineId(current) {
    const convertNull = (value) => {
        if (value === null || value === undefined || value === false) {
            return "";
        } else if (typeof value === "object") {
            // We're using the replaceAll to follow the python
            // behavior where we're stringify a dict.
            return JSON.stringify(value).replaceAll('":', '": ');
        }
        return value;
    };

    return current
        .map(([markup, model, value]) => {
            const lineValues = [convertNull(markup), convertNull(model), convertNull(value)];
            return lineValues.join(LINE_ID_GROUP_DELIMITER);
        })
        .join(LINE_ID_HIERARCHY_DELIMITER);
}

/**
 * Parses a serialized line ID string back into an array of
 * [markup, model, value] tuples.
 * @param {string} lineID - The serialized line ID string
 * @param {boolean} markupAsString - If true, keeps markup as raw string
 * @returns {Array} Array of [markup, model, value] tuples
 */
export function parseLineId(lineID, markupAsString = false) {
    const parseMarkup = (markup) => {
        if (!markup) {
            return markup;
        }
        try {
            const result = JSON.parse(markup);
            return typeof result === "object" ? result : markup;
        } catch {
            return markup;
        }
    };

    if (!lineID) {
        return [];
    }
    return lineID.split(LINE_ID_HIERARCHY_DELIMITER).map((key) => {
        const [markup, model, value] = key.split(LINE_ID_GROUP_DELIMITER);
        return [
            (markupAsString ? markup : parseMarkup(markup)) || null,
            model || null,
            model && value ? parseInt(value) : value || null,
        ];
    });
}

/**
 * Removes tax grouping segments from a line ID, since tax grouping
 * is not relevant for annotations and other per-line operations.
 * @param {string} lineId - The line ID to filter
 * @returns {string} Line ID with tax group entries removed
 */
export function removeTaxGroupingFromLineId(lineId) {
    return buildLineId(
        parseLineId(lineId, true).filter(([markup, model, value]) => {
            return model !== "account.group";
        })
    );
}
