declare var fetch;

import { Util } from './util/util';
import { Storage } from './util/storage';

export class Config {

    _config: any = {};
    _defaults: any;
    _locked = ['_config', '_defaults'];

    constructor() { }

    public get(key: any) {
        return this._config[key];
    }

    public set(key: any, value: any, castToType = false) {
        if (!this.islocked(key)) {
            if (castToType) {
                value = Util.castToType(value);
            }
            return this._config[key] = value;
        } else {
            console.error('Config: property "'+key+'" can not be changed.');
        }
    }

    public add(object: any, extend = false, castToType = false) {
        const self = this;
        if(!extend) {
            Object.keys(object).forEach((key) => {
                self.set(key, object[key] ,castToType);
            });
        }else{
            this.extend(object);
        }
    }

    public async fetch(url, extend = false) {
        const self = this;
        // if(self.get('api_headers')){
        //
        // }
        // let config =  await fetch(url, {headers: self.get('api_headers')})
        let config = await fetch(url)
            .then(function(response) {
                return response.json();
            })
            .catch(function(error) {
                console.log('config fetch error:', error.message);
            });

        if (extend) {
            this.extend(config);
        }else {
            Object.keys(config).forEach((k, i) => {
                self.set(k, config[k]);
            });
        }
        return config;
    }

    public extend(object: any, target: any = this._config) {
        Util.deepAssign(target, object);
    }

    public all() {
        return this._config;
    }

    public getLocalSettings(id) {
        if (window.localStorage && window.localStorage.getItem(id)) {
            this.add(Storage.restoreLocalModel(id));
        }
    }
    public setLocalSettings(id, settings:any = this._config) {
        if (window.localStorage) {
            Storage.saveLocalModel(settings, id);
        }
    }

    public setDefaults(configDefaults) {
        const self = this;
        self._defaults = configDefaults;
        Object.keys(configDefaults).forEach((k) => {
            self.set(k, Util.copy(configDefaults[k]));
        });
    }

    public restoreDefaults() {
        const self = this;
        Object.keys(self._defaults).forEach((k) => {
            self.set(k, self._defaults[k]);
        });
    }

    public islocked(key) {
        // todo:
        this._locked.forEach((k) => {
            if(k===key){
                console.log('Config error: property "'+k+'" is protected');
                return true;
            }
        })
    }




    // todo
    public lock(key) {
        // todo:
        return false;
        // this._locked.forEach((k) => {
        //
        // })
    }
    public unLock(key) {
        // todo:
        // this._locked.forEach((k) => {
        //
        // })
    }


    initXdomain(object) {
        if (typeof window !== 'undefined' && window['xdomain']) {
            window['xdomain'].masters(object.masters);
            window['xdomain'].slaves(object.slaves);
        }
    };



}
