/** @odoo-module */

import {_t, loadLanguages} from "@web/core/l10n/translation";
import {jsToPyLocale} from "@web/core/l10n/utils";
import {TranslationDialog} from "@web/views/fields/translation_dialog";
import {user} from "@web/core/user";
import {onWillStart} from "@odoo/owl";
import {patch} from "@web/core/utils/patch";
import {useService} from "@web/core/utils/hooks";

// Add userUserCurrentLang prop that doesn't exist in Odoo 19's TranslationDialog
TranslationDialog.props = {
    ...TranslationDialog.props,
    userUserCurrentLang: {type: Boolean, optional: true},
};

patch(TranslationDialog.prototype, {
    setup() {
        this.title = _t("Translate: %s", this.props.fieldName);
        this.user = user;
        this.orm = useService("orm");
        this.terms = [];
        this.updatedTerms = {};
        this.translateIsCallable = false;

        onWillStart(async () => {
            const allLanguages = await loadLanguages(this.orm);
            const languages = this.props.userUserCurrentLang
                ? allLanguages.filter((l) => l[0] === jsToPyLocale(user.lang))
                : allLanguages;

            const [translations, context] = await this.loadTranslations(languages);
            this.translateIsCallable = Boolean(context.translation_show_source);

            let id = 1;
            translations.forEach((t) => (t.id = id++));
            this.props.isText = context.translation_type === "text";
            this.props.showSource = context.translation_show_source;

            this.terms = translations.map((term) => {
                const relatedLanguage = languages.find((l) => l[0] === term.lang);
                const termInfo = {
                    ...term,
                    langName: relatedLanguage ? relatedLanguage[1] : term.lang,
                    value: term.value || "",
                };
                if (
                    term.lang === jsToPyLocale(user.lang) &&
                    !this.props.showSource &&
                    !this.props.isComingFromTranslationAlert &&
                    this.props.userLanguageValue
                ) {
                    this.updatedTerms[term.id] = this.props.userLanguageValue;
                    termInfo.value = this.props.userLanguageValue;
                }
                return termInfo;
            });
            this.terms.sort((a, b) => a.langName.localeCompare(b.langName));
        });
    },

    async loadTranslations(languages) {
        const langs = languages.map((l) => l[0]);
        return this.orm.call(
            this.props.resModel,
            "get_field_translations",
            [[this.props.resId], this.props.fieldName, langs]
        );
    },

    async onSave() {
        const translations = {};
        this.terms.forEach((term) => {
            const updatedTermValue = this.updatedTerms[term.id];
            if (term.id in this.updatedTerms && term.value !== updatedTermValue) {
                if (this.translateIsCallable) {
                    if (!translations[term.lang]) {
                        translations[term.lang] = {};
                    }
                    const oldTermValue = term.value || term.source;
                    translations[term.lang][oldTermValue] = updatedTermValue || term.source;
                    translations[term.lang].source = term.source;
                } else {
                    translations[term.lang] = updatedTermValue || false;
                }
            }
        });
        await this.orm.call(
            this.props.resModel,
            "update_field_translations",
            [[this.props.resId], this.props.fieldName, translations]
        );
        await this.props.onSave();
        this.props.close();
    },
});
