import { Icons } from "./types";
export { Icons } from "./types";

/**
 * Retrieves the specified icon.
 *
 * @param {Icons} icon - The icon to retrieve.
 * @returns {Promise<IconData>} - A promise that resolves to the icon data.
 */
export const getIcon = async (icon: Icons): Promise<string> => {
    switch(icon) {
    <% files.forEach(function(file,index) { %>
        case Icons.<%= constCase(file.meta.fileName) %>:
            return (await import("./<%= file.meta.fileName %>")).Icon<%= file.meta.componentName %>;
    <% }); -%>
        default:
            return '';
    }
}

/**
 * Checks if any of the needles are found within any of the haystacks.
 *
 * @param {string | string[]} needle - The string or array of strings to search for.
 * @param {string | string[]} haystack - The string or array of strings to search within.
 * @returns {boolean} - True if any needle is found within any haystack, otherwise false.
 */
const findIt = (needle: string | string[], haystack: string | string[]): boolean => {
    const needles = (Array.isArray(needle) ? needle : [needle]).map(str => str.toLowerCase());
    const haystacks = (Array.isArray(haystack) ? haystack : [haystack]).map(str => str.toLowerCase());

    return needles.some(n => haystacks.some(h => h.includes(n)));
};

/**
 * Checks if the given icon exists in the Icons enum.
 *
 * @param {string} icon - The icon name to check.
 * @returns {boolean} - True if the icon exists, false otherwise.
 */
export const iconExists = (icon: string): boolean => {
    const iconKeys = Object.keys(Icons).filter(key => isNaN(Number(key)));
    const lowerCaseKeys = iconKeys.map(key => key.toLowerCase());
    return lowerCaseKeys.includes(icon.toLowerCase());
};

/**
 * Searches for icons based on a search term and an optional field to search in.
 *
 * @param {string} term - The search term to look for.
 * @param {'name' | 'category' | 'tag' | 'description' | 'title' | undefined} [searchIn] - The specific field to search in. If not provided, all fields will be searched.
 * @returns {Array<{id: string, name: string, title: string, category: string[], tag: string[], description: string}> | undefined} - An array of matching icons or undefined if no matches are found.
 */
export const searchIcon = (
    term: string,
    searchIn: 'name' | 'category' | 'tag' | 'description' | 'title' | undefined = undefined
): {
    id: string;
    name: string;
    title: string;
    category: string[];
    tag: string[];
    description: string;
}[] | undefined => {
    const meta = {};

    const mergedIcons = Object.keys(Icons).map(key => ({
        id: key,
        name: Icons[key as keyof typeof Icons],
        ...meta[key as keyof typeof Icons]
    }));

    const searchFields = searchIn ? [searchIn] : ['name', 'category', 'tag', 'description', 'title'];

    return mergedIcons.filter(icon =>
        searchFields.some(field => findIt(term, icon[field as keyof typeof icon]))
    );
};
