import { UIMLTextarea } from './../ui-ml-textarea';
import { UIMLInput } from './../ui-ml-input';
import { BindingEngine, Container, Disposable, signalBindings } from 'aurelia-framework';
import { Config } from "../../../config";
import { Language } from '../../../model/common-model';
import { EventAggregator } from 'aurelia-event-aggregator';
import { I18N } from 'aurelia-i18n';

export class MLInputHelper {

    private mlInput: UIMLInput | UIMLTextarea;
    private config: Config;
    private i18n: I18N;
    private bindingEngine: BindingEngine;
    private subscribers: Disposable[] = [];

    constructor(mlInput: UIMLInput | UIMLTextarea, private changeSelectedLangageCallback: () => void = null) {
        this.mlInput = mlInput;

        this.config = Container.instance.get(Config);

        this.mlInput.languages = new Array<AnyObject>();
        this.config.globalConfig.configuredLanguages.forEach((lang: Language | any) => {
            this.mlInput.languages.push(lang);
        });

        Container.instance.get(EventAggregator).subscribe('i18n:locale:changed', () =>
            this.changeSelectedLangage()
        );

        this.i18n = Container.instance.get(I18N);
        this.bindingEngine = Container.instance.get(BindingEngine);
    }

    public isTranslatable(): boolean {
        if (this.mlInput.value == null) return false;
        return Object.getOwnPropertyNames(this.mlInput.value).indexOf('_translation') >= 0;
    }

    public changeSelectedLangage() {
        let currentLanguage = this.i18n.getLocale();
        if (currentLanguage == null) currentLanguage = "fr";
        this.mlInput.selectedLanguage = this.config.globalConfig.configuredLanguages.find(l => l.code.toLocaleLowerCase() == currentLanguage);
        if (this.changeSelectedLangageCallback != null) {
            this.changeSelectedLangageCallback();
        }
    }

    public onClear(): void {
        this.langProperties().forEach(p => this.mlInput.value[p] = null);
    }

    public selectedLanguageCodeChanged(newValue, oldValue) {
        if (newValue != null && newValue != oldValue) {
            this.setSelectedLanguage();
        }
    }

    public setSelectedLanguage() {
        this.mlInput.selectedLanguage = this.config.globalConfig.configuredLanguages.find(l =>
            l.code.toLocaleLowerCase() == this.mlInput.selectedLanguageCode.toLocaleLowerCase()
        );
    }

    public disposeSubscribers() {
        if (this.subscribers?.length > 0) {
            this.subscribers.forEach(s => s.dispose());
            this.subscribers = [];
        }
    }

    public rebindSubscribers(callback: () => void = null) {
        this.disposeSubscribers();
        this.langProperties().forEach(p =>
            this.subscribers.push(
                this.bindingEngine
                    .expressionObserver(this.mlInput.value, p)
                    .subscribe(() => {
                        signalBindings("translation-changed");
                        if (callback != null) {
                            callback();
                        }
                    })
            )
        );
    }

    private langProperties(): string[] {
        if (this.mlInput.value != null) {
            const values = Object.values(this.mlInput.value);
            if (values?.length > 0) {
                return Object.keys(values[1]).filter(p => p.startsWith('lang'));
            }
        }
        return [];
    }
}