import { Injectable } from '@angular/core';
import { Platform, Events } from '@ionic/angular';
import { Globalization } from '@ionic-native/globalization/ngx';
import { Translation } from './Translation';
import { HttpClient } from '@angular/common/http';
import { NativeStorage } from '@ionic-native/native-storage/ngx';

@Injectable({
    providedIn: 'root'
})
export class TranslatorService {

    public static LNG_KEY = 'current-language';
    public static EN = 'en';
    public static EN_US = 'en-us';
    public static AR = 'ar';
    public static CURRENT_LANGUAGE = TranslatorService.EN;
    public static CHANGE_EVENT = 'language-changed-event';
    private static translations: any;
    constructor(
        private platform: Platform,
        private glob: Globalization,
        private httpClient: HttpClient,
        private nativeStorage: NativeStorage,
        private events: Events
    ) {
    }


    public static getCurrentLanguageCode(): number {
        switch (TranslatorService.CURRENT_LANGUAGE) {
            case TranslatorService.EN:
                return 2;
            case TranslatorService.AR:
                return 1;
            default:
                return 2;
        }
    }

    public static getCurrentDirection(): string {
        return TranslatorService.getCurrentLanguageName() === TranslatorService.AR ? 'rtl' : 'ltr';
    }

    public async getCurrentSystemLanguageName() {
        const lng = await this.glob.getPreferredLanguage();
        if (lng && lng.value) {
            return lng.value.toLowerCase();
        } else {
            return TranslatorService.EN_US;
        }
    }

    public static getCurrentLanguageName(): string {
        return TranslatorService.CURRENT_LANGUAGE;
    }
    private isLoaded(): boolean {
        return TranslatorService.translations != null;
    }

    /*
    load system translation files
    */
    private loadTranslationAssetNative(onSuccess: any) {
        this.httpClient.get('assets/localization/i18n.json').subscribe(data => {
            TranslatorService.translations = data;
            if (data) {
                if (!this.isSystemLanguageSupported()) {
                    this.setCurrentLanguageToDefault();
                }
                if (onSuccess) {
                    onSuccess();
                }
            }
        });
    }

    private isSystemLanguageSupported(): boolean {
        for (const lng of TranslatorService.translations.SUPPORTED_LANGUAGES) {
            if (TranslatorService.CURRENT_LANGUAGE === lng) {
                return true;
            }
        }
        return false;
    }

    /*
     get current system prefered language
    */
    public loadResourcesNative(onSuccess: any) {
        this.platform.ready().then(() => {
            this.glob.getPreferredLanguage().then(res => {
                const lang = res.value.split('-')[0];
                TranslatorService.CURRENT_LANGUAGE = lang;
                this.loadTranslationAssetNative(onSuccess);
            }).catch(err => {
                this.setCurrentLanguageToDefault();
                this.loadTranslationAssetNative(onSuccess);
            });
        });
    }



    private loadTranslationAsset(onSuccess: any) {
        this.httpClient.get('assets/localization/i18n.json').subscribe(data => {
            TranslatorService.translations = data;
            if (data) {
                if (onSuccess) {
                    onSuccess();
                }
            }
        });
    }

    public loadResources(onSuccess: any) {
        this.platform.ready().then(() => {
            this.nativeStorage.getItem(TranslatorService.LNG_KEY).then((previousLanguage: string) => {
                TranslatorService.CURRENT_LANGUAGE = previousLanguage;
                this.loadTranslationAsset(onSuccess);
            }, () => {
                this.setCurrentLanguageToDefault();
                this.loadTranslationAsset(onSuccess);
            });

        });
    }

    /*
    translate key depend on current prefered language
    */
    public translate(trans: Translation): string {
        if (this.isLoaded()) {
            const page = TranslatorService.translations[trans.page];
            if (page) {
                const word = page[trans.key];
                if (word) {
                    return word[TranslatorService.CURRENT_LANGUAGE];
                }
            }
        }
        return '';
    }

    private isValidTranslation(trans: Translation): boolean {
        if (trans != null) {
            return trans.isValid();
        }
        return false;
    }
    /*
    shortcut for translate
    */
    public tr(trans: Translation): string {
        return this.translate(trans);
    }

    /*
    translate with page and key
    */
    public trPK(page: string, key: string): string {
        return this.translate(new Translation(page, key));
    }

    public trInline(pageKey: string): string {
        if (pageKey) {
            const parts = pageKey.split(',');
            if (parts.length === 2) {
                return this.trPK(parts[0].trim(), parts[1].trim());
            }
        } else {
            return '';
        }
    }

    private setCurrentLanguageToDefault() {
        TranslatorService.CURRENT_LANGUAGE = TranslatorService.EN;
    }
    public setCurrentLanguage(language: string) {
        TranslatorService.CURRENT_LANGUAGE = language;
        this.events.publish(TranslatorService.CHANGE_EVENT);
        this.nativeStorage.setItem(TranslatorService.LNG_KEY, language).then(() => {
        }, () => { });
    }


    public switchLanguage() {

        this.nativeStorage.getItem(TranslatorService.LNG_KEY).then((previousLanguage: string) => {
            this.setCurrentLanguage(this.getNextLanguage(previousLanguage));
        }, () => {
            this.setCurrentLanguage(this.getNextLanguage(TranslatorService.CURRENT_LANGUAGE));
        });
    }

    private getNextLanguage(currentLanguage: string) {
        return (currentLanguage === TranslatorService.EN) ? TranslatorService.AR : TranslatorService.EN;
    }
}


