import * as i0 from '@angular/core';
import { Injectable } from '@angular/core';
import * as i1 from '@c8y/client';
import { ApplicationType, ApplicationAvailability } from '@c8y/client';
import * as i2 from '@c8y/ngx-components';
import { uniq } from 'lodash-es';

class TranslationStoreService {
    constructor(appService, appState, zip) {
        this.appService = appService;
        this.appState = appState;
        this.zip = zip;
        this.translationAppName = 'User defined translations';
        this.translationAppContextPath = 'user-defined-translations';
    }
    /**
     * Retrieves a list of available translations for the given locales from all the hosted apps available on the tenant.
     */
    async getAvailableTranslations(locales) {
        const { data: hostedApps } = await this.appService.list({
            tenant: this.appState.currentTenant.value.name,
            type: 'HOSTED',
            pageSize: 2000
        });
        const uniqueContextPaths = uniq(hostedApps
            .filter(app => app.contextPath && app.manifest?.webSdkVersion)
            .map(app => app.contextPath));
        const translations = {};
        for (const contextPath of uniqueContextPaths) {
            for (const locale of locales) {
                try {
                    const translationsForLanguageAndApp = await this.getFileFromPath(`/apps/${contextPath}/${locale}.json`);
                    for (const key of Object.keys(translationsForLanguageAndApp)) {
                        if (!translations[key]) {
                            translations[key] = {};
                        }
                        translations[key][locale] = translationsForLanguageAndApp[key];
                    }
                }
                catch (e) {
                    continue;
                }
            }
        }
        return translations;
    }
    /**
     * Retrieves the translations for the given locale from the translation app.
     */
    async getTranslationsForLocale(locale) {
        try {
            const translations = await this.getFileFromTranslationApp(`${locale}.json`);
            if (translations[locale]) {
                return translations[locale];
            }
        }
        catch (e) {
            // do nothing.
        }
        return {};
    }
    /**
     * Retrieves the translations for the given locales from the translation app.
     */
    async loadTranslationsForLocales(locales) {
        const translations = {};
        const loadAndAddLocale = async (locale) => {
            translations[locale] = await this.getTranslationsForLocale(locale);
        };
        await Promise.all(locales.map(loadAndAddLocale));
        return translations;
    }
    /**
     * Retrieves a combined list of translations for all the provided locales.
     * The locales are combined into a single object per key and an array of these objects is returned.
     */
    async getCombinedListOfTranslationsForPerKey(locales) {
        const translations = await this.loadTranslationsForLocales(locales);
        const translationMap = {};
        for (const locale of Object.keys(translations)) {
            for (const key of Object.keys(translations[locale])) {
                let translationsForKey = translationMap[key];
                if (!translationsForKey) {
                    translationsForKey = {};
                    translationMap[key] = translationsForKey;
                }
                translationsForKey[locale] = translations[locale][key];
            }
        }
        const keys = Object.keys(translationMap).sort((a, b) => a.localeCompare(b));
        return keys.map(key => Object.assign({ key }, translationMap[key]));
    }
    /**
     * Updates the files of the translation application with the provided translations.
     */
    async updateTranslations(translations) {
        const filesToUpload = new Array();
        const translationsPerLocale = {};
        for (const entry of translations) {
            const key = entry.key;
            for (const locale of Object.keys(entry)) {
                if (locale === 'key') {
                    continue;
                }
                if (!translationsPerLocale[locale]) {
                    translationsPerLocale[locale] = {};
                }
                if (entry[locale]) {
                    translationsPerLocale[locale][key] = entry[locale];
                }
            }
        }
        const langs = this.appState.state.langs;
        for (const locale of langs) {
            const fileName = `${locale}.json`;
            filesToUpload.push({
                path: fileName,
                contents: new File([JSON.stringify({ [locale]: translationsPerLocale[locale] || {} })], fileName)
            });
        }
        const app = await this.getOrCreateTranslationApp();
        await this.appService.binary(app).updateFiles(filesToUpload);
    }
    /**
     * @returns The translation app for the current tenant. If it does not exist, it will be created.
     */
    async getOrCreateTranslationApp() {
        const { data: apps } = await this.appService.listByName(this.translationAppName);
        const ownApp = apps.find(app => app.contextPath === this.translationAppContextPath &&
            app.owner.tenant.id === this.appState.currentTenant.value.name);
        if (ownApp) {
            return ownApp;
        }
        const { data: app } = await this.appService.create({
            name: this.translationAppName,
            contextPath: this.translationAppContextPath,
            key: `${this.translationAppContextPath}-app-key`,
            type: ApplicationType.HOSTED,
            availability: ApplicationAvailability.MARKET,
            config: {
                icon: {
                    class: 'language1'
                }
            },
            noAppSwitcher: true,
            description: 'Providing user defined translations'
        });
        const zip = await this.zip.createZip([]);
        const { data: binary } = await this.appService.binary(app).upload(zip, 'translations.zip');
        const { data: updatedApp } = await this.appService.update({
            id: app.id,
            activeVersionId: binary.id
        });
        return updatedApp;
    }
    async getFileFromTranslationApp(file) {
        return this.getFileFromPath(`/apps/public/${this.translationAppContextPath}/${file}`);
    }
    async getFileFromPath(path) {
        const finalPath = `${path}?nocache=${Date.now()}`;
        const response = await fetch(finalPath);
        if (response.status !== 200) {
            throw new Error(`Failed to fetch file from ${path}`);
        }
        return response.json();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslationStoreService, deps: [{ token: i1.ApplicationService }, { token: i2.AppStateService }, { token: i2.ZipService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslationStoreService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslationStoreService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i1.ApplicationService }, { type: i2.AppStateService }, { type: i2.ZipService }] });

/**
 * Generated bundle index. Do not edit.
 */

export { TranslationStoreService };
//# sourceMappingURL=c8y-ngx-components-translation-editor-data.mjs.map
