import assert from 'node:assert';
import cloudron from './cloudron.js';
import logger from './logger.js';
import fs from 'node:fs';
import path from 'node:path';
import paths from './paths.js';
import safe from 'safetydance';

const { log } = logger('translation');


// to be used together with getTranslations() => { translations, fallback }
function translate(input, assets) {
    assert.strictEqual(typeof input, 'string');
    assert.strictEqual(typeof assets, 'object');
    assert.strictEqual(typeof assets.translations, 'object');
    assert.strictEqual(typeof assets.fallback, 'object');

    const { translations, fallback } = assets;

    const tokens = input.match(/{{(.*?)}}/gm);
    if (!tokens) return input;

    let output = input;
    for (const token of tokens) {
        const key = token.slice(2).slice(0, -2).trim();
        let value = key.split('.').reduce(function (acc, cur) {
            if (acc === null) return null;
            return typeof acc[cur] !== 'undefined' ? acc[cur] : null;
        }, translations);

        // try fallback
        if (value === null) value = key.split('.').reduce(function (acc, cur) {
            if (acc === null) return null;
            return typeof acc[cur] !== 'undefined' ? acc[cur] : null;
        }, fallback);

        if (value === null) value = token;

        output = output.replace(token, value);
    }

    return output;
}

async function getTranslations() {
    const fallbackData = fs.readFileSync(path.join(paths.TRANSLATIONS_DIR, 'en.json'), 'utf8');
    if (!fallbackData) log(`getTranslations: Fallback language en not found. ${safe.error.message}`);
    const fallback = safe.JSON.parse(fallbackData) || {};

    const lang = await cloudron.getLanguage();

    const translationData = safe.fs.readFileSync(path.join(paths.TRANSLATIONS_DIR, `${lang}.json`), 'utf8');
    if (!translationData) log(`getTranslations: Requested language ${lang} not found. ${safe.error.message}`);
    const translations = safe.JSON.parse(translationData) || {};

    return { translations, fallback };
}

async function listLanguages() {
    const [error, result] = await safe(fs.promises.readdir(paths.TRANSLATIONS_DIR));
    if (error) {
        log(`listLanguages: Failed to list translations. %${error.message}`);
        return [ 'en' ]; // we always return english to avoid dashboard breakage
    }

    const jsonFiles = result.filter(function (file) { return path.extname(file) === '.json'; });
    const languages = jsonFiles.map(function (file) { return path.basename(file, '.json'); });
    return languages;
}

export default {
    translate,
    getTranslations,
    listLanguages
};
