import { Injectable } from '@angular/core';
import {ApiService} from './api.service';
import {debounce} from '../utility';

@Injectable({
    providedIn: 'root'
})
export class SessionService {
    public appName!: string;
    public systemBase!: string;
    protected data: any = {};
    protected saveTriggered = false;
    protected saving = false;
    protected loadedVersion = '';
    protected privTriggerSave = debounce(() => {
        if ( this.saving ) {
            this.triggerSave();
        } else {
            this.save();
        }

        this.saveTriggered = false;
    }, 3000);

    public triggerSave() {
        this.saveTriggered = true;
        this.privTriggerSave();
    }

    public get version() {
        return this.loadedVersion;
    }

    constructor(
        protected readonly api: ApiService,
    ) { }

    async newVersionAvailable() {
        return (await this.api.version()) !== this.loadedVersion;
    }

    async stat() {
        this.loadedVersion = await this.api.version();

        return new Promise((res, rej) => {
            this.api.stat().subscribe(response => {
                res(response.data);
            });
        });
    }

    async initialize() {
        this.data = await this.api.getSessionData();
    }

    async save() {
        this.saving = true;
        await this.api.saveSessionData(this.data);
        this.saving = false;
    }

    buildAppUrl(...parts: string[]): string {
        parts = parts.map(x => {
            if ( x.startsWith('/') ) {
                x = x.slice(1);
            }

            if ( x.endsWith('/') ) {
                x = x.slice(0, -1);
            }

            return x;
        });

        return `${this.systemBase}${this.systemBase.endsWith('/') ? '' : '/'}${parts.join('/')}`;
    }

    get(path?: string): any {
        let current: any = this.data;
        if ( !path ) {
            return current;
        }

        const parts = path.split('.');
        for ( const part of parts ) {
            current = current?.[part];
        }

        return current;
    }

    set(pathOrValue: string | any, value?: any): any {
        if ( typeof pathOrValue !== 'string' ) {
            this.data = pathOrValue;
            return;
        }

        if ( typeof value === 'undefined' ) {
            return;
        }

        const parts = pathOrValue.split('.');
        let last;
        let current = this.data;

        for ( const part of parts ) {
            last = current;
            current = current?.[part];
        }

        parts.reverse();
        if ( last ) {
            last[parts[0]] = value;
        }

        this.triggerSave();
    }
}
