/**
 * checks against emptiness, true when undefined, empty string, empty object, empty array
 * @param data
 * @return {boolean}
 */
const isEmpty = (data) => {
    if('undefined' === typeof data || null === data) {
        return true;
    }

    return (
        '' === data ||
        {} === data ||
        (
            'object' === typeof data && (
                null === data.length
                || 1 > data.length
            )
        )
    );
};


class ContentStore {
    constructor() {
        this.evtN = {};
        this.data = {};
    }

    clear() {
        this.evtN = {};
    }

    save = () => {
        this._saveN.trigger();
        return this.data;
    };

    _saveN = {
        addSave: (id, evt) => {
            if('function' === typeof evt) {
                this.evtN[id] = evt;
            } else {
                console.error('ContentStore, saveN.addSave evt is not a function in `' + id + '`');
            }
        },

        rmSave: (id) => {
            if(this.evtN.hasOwnProperty(id)) {
                delete this.evtN[id];
            }
        },

        trigger: () => {
            for(let id in this.evtN) {
                if(this.evtN.hasOwnProperty(id)) {
                    this.evtN[id]();
                }
            }
        }
    };

    _createItem = (id, saveData) => {
        /**
         * Context based saving event wrapper
         *
         * @param id unique id, not just single ident, as child in two separate lists would overwrite them self otherwise
         * @param evt
         */
        const addSave = (id, evt) => {
            if('function' === typeof evt) {
                const ev = () => {
                    return saveData(evt());
                };

                this._saveN.addSave(id, ev);
            } else {
                console.error('ContentStore, _createItem.addSave evt is not a function in `' + id + '`');
            }
        };

        return {
            addSave: addSave,
            rmSave: this._saveN.rmSave,
        };
    };

    createGroup = (id, data = false) => {
        let d = this.data;
        if(data) {
            d = data;
        }

        d[id] = {};

        const saveData = (data) => {
            if(isEmpty(data)) {
                delete d[id];
            } else {
                d[id] = data;
            }
            return data;
        };

        return {
            createGroup: (gid) => {
                return this.createGroup(gid, d[id]);
            },
            createItem: (iid) => {
                return this._createItem(iid, saveData);
            }
        };
    };

    createList = () => {
        this.data = {};

        const saveData = (id, data) => {
            if(isEmpty(data)) {
                delete this.data[id];
            } else {
                this.data[id] = data;
            }

            return data;
        };

        return {
            /**
             * @param id
             * @return {{addSave, rmSave}}
             */
            createItem: (id) => {
                const savDat = (data) => {
                    return saveData(id, data);
                };
                return this._createItem(id, savDat);
            },
            /**
             * @param id
             */
            deleteItem: (id) => {
                delete this.data[id];
            }
        };
    };
}

class SaveSingle {
    constructor() {
        this.evt = false;
    }

    clear() {
        this.evt = false;
    }

    trigger = () => {
        if(this.evt) {
            return this.evt();
        }
    };

    addSave = (evt = false) => {
        if(evt) {
            this.evt = evt;
        }
    };

    rmSave = () => {
        this.evt = false;
    };
}

export default ContentStore;

export {SaveSingle};