import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { MatPaginatorIntl } from '@angular/material/paginator';
import { Subject } from 'rxjs';

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

    locale: string = "de-informal";
    locales: any[] = ["de-informal"];
    i18n: any;

    constructor(private http: HttpClient) {

    }

    getLocales() {
        return this.locales;
    }

    getLocale() {
        return this.locale || 'de-informal';
    }

    setLocale(locale) {
        this.locale = locale;
    }

    async fetch() {

        let browserLocale = navigator.language;

        if (browserLocale.indexOf("-") != -1) {
            browserLocale = browserLocale.split("-")[0];
        }

        let locale = localStorage.getItem("buntspecht.locale") || browserLocale || this.locales[0];

        if (locale == 'de') {
            locale = 'de-informal';
        }

        if (this.locales.indexOf(locale) == -1) {
            locale = this.locales[0];
        }

        this.setLocale(locale);
        this.i18n = await this.http.get("/assets/i18n/" + locale + ".json").toPromise();
        console.debug("fallback to default locale");

    }

    get(key, args: string[]): string {
        return this.getInternal(key, args, this.i18n, "", true);
    }

    getEmpty(key, args: string[]): string {
        return this.getInternal(key, args, this.i18n, "", false);
    }

    getInternal(key, args: string[], from, path, empty: boolean): string {
        key += '';
        if (!from) {
            return empty ? this.empty(key, args, path) : (key || "");
        } else if (from[key]) {
            if (typeof from[key] === 'object') {
                if (from[key]["."]) {
                    return this.insertArguments(from[key]["."], args);
                }
                return empty ? this.empty(key, args, path) : (key || "");
            }
            return this.insertArguments(from[key], args);
        } else {
            let keys = key.split(".");
            if (from[keys[0]]) {
                key = keys.slice(1, keys.length).join(".");
                return this.getInternal(key, args, from[keys[0]], path + keys[0] + ".", empty)
            }
        }

        return empty ? this.empty(key, args, path) : (key || "");
    }

    empty(key, args: string[], path: string): string {
        return (path ? path + (path.endsWith(".") ? "" : ".") : "") + key + (args && args.length > 0 ? (" [" + args + "]") : "");
    }

    insertArguments(label: string, args: string[]) {
        if (args) {
            for (let index in args) {
                label = label.replace(`{${index}}`, this.get(args[index], null));
            }
        }
        return label;
    }

}


@Injectable()
export class I18nPaginatorIntl implements MatPaginatorIntl {

    changes = new Subject<void>();

    i18n: I18nService;

    itemsPerPageLabel: string;
    nextPageLabel: string;
    previousPageLabel: string;
    firstPageLabel: string;
    lastPageLabel: string;


    injectI18n(i18n: I18nService) {
        this.i18n = i18n;

        this.firstPageLabel = this.i18n.get('paginator.firstPage', []);
        this.itemsPerPageLabel = this.i18n.get('paginator.itemsPerPage', []);
        this.lastPageLabel = this.i18n.get('paginator.lastPage', []);

        this.nextPageLabel = this.i18n.get('paginator.nextPage', []);
        this.previousPageLabel = this.i18n.get('paginator.previousPage', []);

    }


    getRangeLabel(page: number, pageSize: number, length: number): string {
        if (length === 0) {
            return this.i18n.get('paginator.empty', []);
        }

        const amountPages = Math.ceil(length / pageSize);
        return this.i18n.get('paginator.range', [page + 1 + "", amountPages + ""]);
    }
}