export class ShopIconCatalogRegistry {
    static #catalogs = new Map();

    static register(definition = {}) {
        const id = String(definition.id || "").trim();
        if (!id) throw new Error("Shop icon catalog definitions require an id.");
        const catalog = {
            id,
            moduleId: String(definition.moduleId || "").trim(),
            label: String(definition.label || id).trim(),
            getIcons: typeof definition.getIcons === "function" ? definition.getIcons : () => definition.icons || []
        };
        this.#catalogs.set(id, catalog);
        Hooks.callAll("augurNexusShopIconCatalogsChanged", { reason: "register", catalog: this.#toPublic(catalog) });
        return this.#toPublic(catalog);
    }

    static list() {
        return [...this.#catalogs.values()].sort((a, b) => a.label.localeCompare(b.label)).map(catalog => this.#toPublic(catalog));
    }

    static async getIcons() {
        const icons = [];
        for (const catalog of this.#catalogs.values()) {
            const entries = await catalog.getIcons();
            for (const entry of Array.isArray(entries) ? entries : []) {
                const icon = this.#normalizeIcon(entry, catalog);
                if (icon) icons.push(icon);
            }
        }
        return icons.sort((a, b) => a.sortLabel.localeCompare(b.sortLabel));
    }

    static async getIcon(id) {
        const needle = String(id || "").trim();
        if (!needle) return null;
        return (await this.getIcons()).find(icon => icon.id === needle) || null;
    }

    static #normalizeIcon(entry = {}, catalog) {
        const imageSrc = String(entry.imageSrc || entry.src || "").trim();
        if (!imageSrc) return null;
        const localId = String(entry.id || imageSrc).trim();
        const id = localId.startsWith(`${catalog.id}:`) ? localId : `${catalog.id}:${localId}`;
        const label = String(entry.label || entry.name || this.#labelFromPath(imageSrc)).trim();
        return {
            id,
            catalogId: catalog.id,
            moduleId: catalog.moduleId,
            label,
            imageSrc,
            tags: [...new Set((entry.tags || []).map(String).filter(Boolean))],
            sortLabel: `${catalog.label} ${label}`.trim()
        };
    }

    static #labelFromPath(path = "") {
        return String(path).split(/[\\/]/).pop()?.replace(/\.[^.]+$/, "")?.replace(/[_-]+/g, " ") || "Shop";
    }

    static #toPublic(catalog) { return { id: catalog.id, moduleId: catalog.moduleId, label: catalog.label }; }
}
