import { Injectable } from '@angular/core';
import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { BaseComponent } from '@common/base/base.component';
import { catchError, takeUntil } from 'rxjs/operators';
import { Observable, throwError } from 'rxjs';
import { HelpService } from '@app/core/model/configuration-models/help-service.model';
import { LoginProviders } from '@app/core/model/configuration-models/login-providers.model';
import { Logging } from '@app/core/model/configuration-models/logging.model';
import { HttpClient } from '@angular/common/http';

@Injectable({
	providedIn: 'root',
})
export class ConfigurationService extends BaseComponent {

	constructor(private http: HttpClient) { super(); }

	private _server: string;
	get server(): string {
		return this._server;
	}

	private _app: string;
	get app(): string {
		return this._app;
	}

	private _helpService: HelpService;
	get helpService(): HelpService {
		return this._helpService;
	}

	private _defaultCulture: string;
	get defaultCulture(): string {
		return this._defaultCulture;
	}

	private _defaultLanguage: string;
	get defaultLanguage(): string {
		return this._defaultLanguage;
	}

	private _loginProviders: LoginProviders;
	get loginProviders(): LoginProviders {
		return this._loginProviders;
	}

	private _logging: Logging;
	get logging(): Logging {
		return this._logging;
	}

	private _lockInterval: number;
	get lockInterval(): number {
		return this._lockInterval;
	}

	private _guideAssets: string;
	get guideAssets(): string {
		return this._guideAssets;
	}

	private _allowOrganizationCreator: boolean;
	get allowOrganizationCreator(): boolean {
		return this._allowOrganizationCreator;
	}

	private _useSplash: string;
	get useSplash(): string {
		return this._useSplash;
	}

	private _orcidPath: string;
	get orcidPath(): string {
		return this._orcidPath;
	}

	private _matomoEnabled: boolean;
	get matomoEnabled(): boolean {
		return this._matomoEnabled;
	}

	private _matomoSiteUrl: string;
	get matomoSiteUrl(): string {
		return this._matomoSiteUrl;
	}

	private _matomoSiteId: number;
	get matomoSiteId(): number {
		return this._matomoSiteId;
	}

	private _maxFileSizeInMB: number;
	get maxFileSizeInMB(): number {
		return this._maxFileSizeInMB;
	}

	public loadConfiguration(): Promise<any> {
		return new Promise((r, e) => {

			// We need to exclude all interceptors here, for the initial configuration request.
			const params = new BaseHttpParams();
			params.interceptorContext = {
				excludedInterceptors: [InterceptorType.AuthToken,
				InterceptorType.JSONContentType,
				InterceptorType.Locale,
				InterceptorType.ProgressIndication,
				InterceptorType.RequestTiming,
				InterceptorType.UnauthorizedResponse]
			};

			this.http.get('./assets/config/config.json', { params: params }).pipe(catchError((err: any, caught: Observable<any>) => throwError(err)))
				.pipe(takeUntil(this._destroyed))
				.subscribe(
					(content: ConfigurationService) => {
						this.parseResponse(content);
						r(this);
					},
					reason => e(reason));
		});
	}

	private parseResponse(config: any) {
		this._server = config.Server;
		this._app = config.App;
		this._helpService = HelpService.parseValue(config.HelpService);
		this._defaultCulture = config.defaultCulture;
		this._defaultLanguage = config.defaultLanguage;
		this._loginProviders = LoginProviders.parseValue(config.loginProviders);
		this._logging = Logging.parseValue(config.logging);
		this._lockInterval = config.lockInterval;
		this._guideAssets = config.guideAssets;
		this._allowOrganizationCreator = config.allowOrganizationCreator;
		this._useSplash = config.useSplash;
		this._orcidPath = config.orcidPath;
		if (config.matomo) {
			this._matomoEnabled = config.matomo.enabled;
			this._matomoSiteUrl = config.matomo.url;
			this._matomoSiteId = config.matomo.siteId;
		}
		this._maxFileSizeInMB = config.maxFileSizeInMB;
	}

}
