import { fromEvent } from 'rxjs';
import { pluck } from 'rxjs/operators';
import { PermissionsService, User, Util } from "@ema/core";
import { BaseService } from "@ema/core";
import { StateService } from '@ema/rx';
import * as actions from './app-store';
import reducer from './app-store';
import * as uaasActions from './actions/uaas-store';
import uaasReducer from './actions/uaas-store';
const singleton = Symbol();
const singletonEnforcer = Symbol();
export class AppService {
    constructor(enforcer) {
        this.baseUrl = '';
        this.loading = true;
        this.authenticated = false;
        this.errorMessage = '';
        if (enforcer !== singletonEnforcer) {
            throw new Error('Cannot construct singleton');
        }
        this.base = BaseService.instance;
        this.stateService = StateService.instance;
        this.permissions = PermissionsService.instance;
        this.translation = this.base.translation;
        this.config = this.base.config;
        this.user = new User('visitor');
        this.init().then(() => {
            this.stateService.actions.setState('initialized', true);
            this.test();
        });
    }
    async init() {
        this.initStores();
        await this.base.initApp(this.baseUrl + '/assets/config.json', true, '_emaApp');
        await this.permissions.loadRules(this.baseUrl + '/assets/permissions.json', true, 'rules');
        this.base.translation.use(this.config.get('language'));
        this.data = {};
        this.data.manifest = await Util.fetchJson(this.baseUrl + '/assets/collection-manifest.json');
        this.data.mockData = await Util.fetchJson(this.baseUrl + '/assets/data/mock-data.json');
        this.data.dwpData = await Util.fetchJson(this.baseUrl + '/assets/data/mock-dwp.json');
        this.data.swaggerData = await Util.fetchJson(this.baseUrl + '/assets/data/apiSwagger.json');
        this.collectionManifest = this.data.manifest;
        this.parseComponents();
        this.initHistory();
        this.initSketchListeners();
        if (window.document.location.hostname.match('localhost'))
            this.config.set('dev', true);
    }
    async initStores() {
        this.globalState$ = this.stateService.globalState$;
        this.globalState$.pipe(pluck('initialized')).subscribe((state) => {
            this.initialized = state;
        });
        this.state$ = this.stateService.createCombinedStore({ app: reducer, uaas: uaasReducer }, { foo: 'bar' });
        this.state$.subscribe((state) => {
        });
        this.uaas$ = this.stateService.createStore(uaasReducer, Object.assign({}, uaasActions.initialState, { clientId: 'es-nl-config', custom: 'ja ja' }));
        this.uaas$.pipe(pluck('subKey')).subscribe((state) => {
        });
    }
    initSketchListeners() {
        fromEvent(document, 'sketch-artboard-init').subscribe((event) => {
            console.log('sketch init: ', event.detail.selector);
        });
        fromEvent(document, 'sketch-artboard-update').subscribe((event) => {
            console.log('sketch update: ', event.detail.selector);
        });
        fromEvent(document, 'svgElementClick').subscribe((event) => {
            let id = event.detail.id;
            let el = event.detail.el;
            if (id.match('btn-logo')) {
                this.showFlashMessage('Called from sketch: id=' + id, 'primary', 2000);
            }
            if (id.match('icon-sketch')) {
            }
            console.log('svg: id = ', event.detail.id);
        });
    }
    test() {
        console.log('test');
        this.stateService.actions.addConfig(this.config.all());
        actions.changeName('Bob');
        uaasActions.subAction('uaas payload');
        this.stateService.actions.setConfig('foo', 'bar');
        actions.changeName('Bob de bouwer');
        this.stateService.set('foo', 'global bar');
    }
    initHistory() {
        if (typeof window !== 'undefined' && window.history) {
        }
    }
    parseComponents() {
        let allComps = Util.copy(this.data.manifest.components);
        let components = [];
        allComps.map((c) => {
            let tag = c.tag;
            let ignore = false;
            this.config.get('componentsIgnorePatterns').forEach((p) => {
                if (tag.match(p)) {
                    ignore = true;
                }
            });
            if (!ignore) {
                components.push(c);
            }
        });
        this.components = components;
    }
    showFlashMessage(message, type, duration = 2000) {
        document.querySelector('ema-flash-message').show(message, type, duration);
    }
    static get instance() {
        if (!this[singleton]) {
            this[singleton] = new AppService(singletonEnforcer);
        }
        return this[singleton];
    }
}
