import { h } from "@stencil/core";
const daysOfWeek = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday"
];
/**
 * @param element an HTMLElement
 * @returns an alphabetically ordered array of all the parts and exportparts the element contains.
 */
export const getElementSelectorParts = (element) => {
    var _a, _b;
    const queries = [];
    const elementParts = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[part]`);
    const elementExportParts = (_b = element.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelectorAll(`[exportparts]`);
    elementParts === null || elementParts === void 0 ? void 0 : elementParts.forEach(el => {
        queries.push(`${element.tagName.toLowerCase()}::part(${el.getAttribute("part")})`);
    });
    elementExportParts === null || elementExportParts === void 0 ? void 0 : elementExportParts.forEach(el => {
        queries.push(...[
            ...el.getAttribute("exportparts").matchAll(/(?:[\w-]+:)?([\w-]+)/g)
        ].map(item => `${element.tagName.toLowerCase()}::part(${item[1]})`));
    });
    return queries.sort();
};
/**
 * @param selector a part selector
 * @returns A reference to the element the part belongs to.
 */
export const querySelectorPart = (selector) => {
    const querySelectorDeep = (element, parts) => {
        const shadow = element.shadowRoot;
        const partList = parts.split(" ");
        const partElement = shadow.querySelector(partList.map(partName => `[part~="${partName}"]`).join(""));
        if (partElement) {
            return partElement;
        }
        const exportPartElement = shadow.querySelector(partList.map(partName => `[exportparts*="${partName}"]`).join(""));
        if (exportPartElement) {
            const exportPartList = [];
            const exportparts = exportPartElement.getAttribute("exportparts");
            partList.forEach(partItem => {
                const exportPartName = exportparts.match(`(?:([\\w-]+):)?(${partItem})`)[1];
                if (exportPartName) {
                    exportPartList.push(exportPartName);
                }
            });
            if (partList.length === exportPartList.length) {
                return querySelectorDeep(exportPartElement, exportPartList.join(" "));
            }
        }
        return null;
    };
    const selectorItems = selector.match("(.*)::part\\(([^)]+)\\)");
    const entity = selectorItems[1];
    const partName = selectorItems[2];
    return querySelectorDeep(document.querySelector(entity), partName);
};
const daysFromToday = (date) => {
    const today = new Date();
    // To calculate the time difference of two dates
    const timeDifference = today.getTime() - date.getTime();
    // To calculate the no. of days between two dates
    const daysDifference = timeDifference / (1000 * 3600 * 24);
    return Math.floor(daysDifference);
};
// - - - - - - - - - - - -
// Date Functions
// - - - - - - - - - - - -
const isToday = (date) => {
    const today = new Date();
    if (today.toDateString() === date.toDateString()) {
        return true;
    }
    return false;
};
const isYesterday = (date) => {
    const yesterday = new Date();
    yesterday.setDate(yesterday.getDate() - 1);
    if (yesterday.toDateString() === date.toDateString()) {
        return true;
    }
    return false;
};
export const formatDate = (date, type = "date-time") => {
    var _a;
    let formattedDate;
    // validate date
    // undefined or null
    if (date === undefined || date === null) {
        return "";
    }
    // If the date object is invalid it will return 'NaN' on getTime() and NaN is never equal to itself
    const dateIsValid = date.getTime() === date.getTime();
    if (!dateIsValid) {
        return "Invalid date";
    }
    let locale = "en-US";
    const lang = (_a = document
        .getElementsByTagName("html")[0]
        .getAttribute("lang")) === null || _a === void 0 ? void 0 : _a.valueOf();
    if (lang === "es") {
        locale = "es-ES";
    }
    formattedDate = date.toLocaleDateString(locale);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    const hours = String(date.getHours()).padStart(2, "0");
    const minutes = String(date.getMinutes()).padStart(2, "0");
    const time = `${hours}:${minutes}`;
    if (type === "date-time") {
        formattedDate += `  ${date.toLocaleTimeString()}`;
    }
    else if (type === "date-time-short") {
        // No seconds
        formattedDate = `${year}/${month}/${day} ${time}`;
    }
    else {
        // pretty
        const daysPassedFromToday = daysFromToday(date);
        const today = new Date();
        const currentYear = today.getFullYear();
        if (isToday(date)) {
            return `Today ${time}`;
        }
        else if (isYesterday(date)) {
            return `Yesterday ${time}`;
        }
        else if (daysPassedFromToday <= 7) {
            // If one week or less, just show the day of the week, and the time
            const day = daysOfWeek[date.getDay()];
            return `${day} ${time}`;
        }
        else if (currentYear === year) {
            // If current year, show day number and month name. Example: November 17th
            if (locale === "es-ES") {
                formattedDate = `${day} de ${date.toLocaleString("es-ES", {
                    month: "long"
                })} ${time}`;
            }
            else {
                formattedDate = `${date.toLocaleString("en-US", {
                    month: "long"
                })} ${day} ${time}`;
            }
        }
        else {
            // Display date as usual
            formattedDate = formatDate(date, "date-time-short");
        }
    }
    return formattedDate;
};
// - - - - - - - - - - - -
// /End of Date Functions
// - - - - - - - - - - - -
/* Count the total tree nodes (by default it does not count the first level nodes)*/
export const countTreeItems = (treeModel, children = false) => {
    let totalNodes = 0;
    treeModel.forEach(node => {
        children && totalNodes++;
        if (node.items) {
            totalNodes += countTreeItems(node.items, true);
        }
    });
    return totalNodes;
};
/**
 * @description it evaluates the initial selected combo item
 * @param options an array of GxOption
 * @returns the initial combo value, which in this case is the id
 */
export const setInitialComboValue = (options) => {
    const selected = options.find(option => option.selected);
    if (selected) {
        return selected.value || selected.id;
    }
    else {
        return options[0].value || options[0].id;
    }
};
export const escapeRegExp = (str) => {
    return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
};
/**
 * @description this function highlights the character(s) that match(es) the filter value.
 * hiChar comes from (hi)light (Char)acters
 * @param text the string to find the filter value on
 * @param filterValue the filter value
 * @returns a span element
 */
export const hiChar = function (text, filterValue) {
    if (text && filterValue) {
        const escapedFilterValue = escapeRegExp(filterValue);
        const re = new RegExp(escapedFilterValue, "gi");
        return (h("span", { innerHTML: text.replace(re, '<span class="hiChar">$&</span>') }));
    }
    else {
        return text;
    }
};
export const closeOnOutsideClickHandler = (eventInfo, ref) => {
    if (!eventInfo.composedPath().includes(ref)) {
        return true;
    }
};
export const mapOptionsToComboBoxItemModel = (options) => options.map(option => ({
    value: option.id,
    caption: option.label
    // startImgSrc: option.iconName
}));
export const renderChCheckboxItems = (options, frontEndCheckboxInputHandler, checkedIds) => {
    return options === null || options === void 0 ? void 0 : options.map(option => {
        const value = checkedIds === null || checkedIds === void 0 ? void 0 : checkedIds.find(id => option.value === id || option.id === id);
        return (h("ch-checkbox", { name: option.name, class: "checkbox", checkedValue: option.value || option.id, caption: option.label, disabled: option.disabled, value: value, onInput: frontEndCheckboxInputHandler, startImgSrc: option.iconName, key: option.value || option.id }));
    });
};
//# sourceMappingURL=helpers.js.map
