import { InjectionToken, ɵɵdefineInjectable, ɵɵinject, Injectable, Inject, Optional } from '@angular/core';
import { __classPrivateFieldGet, __awaiter } from 'tslib';
import hash from 'object-hash';
import { BehaviorSubject } from 'rxjs';
import { startWith, switchMap } from 'rxjs/operators';

const SETTING_CONFIG = new InjectionToken('setting.configuration');

var _cache, _subject, _observer, _get, _getServer, _set, _setServer, _has, _hasServer, _remove, _removeServer;
class SdSettingService {
    constructor(configuration) {
        this.configuration = configuration;
        _cache.set(this, {});
        _subject.set(this, {});
        _observer.set(this, {});
        _get.set(this, (key, option) => {
            return () => {
                let cache = __classPrivateFieldGet(this, _cache)[key];
                if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                    try {
                        cache = JSON.parse(sessionStorage.getItem(key));
                    }
                    catch (_a) {
                        cache = undefined;
                    }
                }
                else {
                    try {
                        cache = JSON.parse(localStorage.getItem(key));
                    }
                    catch (_b) {
                        cache = undefined;
                    }
                }
                if (!cache) {
                    return option === null || option === void 0 ? void 0 : option.default;
                }
                if (cache.data === undefined) {
                    return undefined;
                }
                return JSON.parse(JSON.stringify(cache.data));
            };
        });
        _getServer.set(this, (key, option) => {
            return () => __awaiter(this, void 0, void 0, function* () {
                var _a;
                let cache = __classPrivateFieldGet(this, _cache)[key];
                try {
                    cache = yield ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.get(key, option));
                }
                catch (_b) {
                    cache = undefined;
                }
                if (!cache) {
                    return option === null || option === void 0 ? void 0 : option.default;
                }
                if (cache.data === undefined) {
                    return undefined;
                }
                return JSON.parse(JSON.stringify(cache.data));
            });
        });
        _set.set(this, (key, option) => {
            return (data) => {
                const clonedData = data === undefined ? undefined : JSON.parse(JSON.stringify(data));
                __classPrivateFieldGet(this, _cache)[key] = {
                    data: clonedData,
                    createdOn: new Date(),
                };
                const storagedData = JSON.stringify(__classPrivateFieldGet(this, _cache)[key]);
                if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                    try {
                        sessionStorage.setItem(key, storagedData);
                        __classPrivateFieldGet(this, _subject)[key].next(__classPrivateFieldGet(this, _cache)[key].data);
                    }
                    catch (err) {
                        console.error(err);
                    }
                }
                else {
                    try {
                        localStorage.setItem(key, storagedData);
                        __classPrivateFieldGet(this, _subject)[key].next(__classPrivateFieldGet(this, _cache)[key].data);
                    }
                    catch (err) {
                        console.error(err);
                    }
                }
            };
        });
        _setServer.set(this, (key, option) => {
            return (data) => __awaiter(this, void 0, void 0, function* () {
                var _a;
                if (data === undefined) {
                    __classPrivateFieldGet(this, _cache)[key] = {
                        data: undefined,
                        createdOn: new Date(),
                    };
                }
                else {
                    __classPrivateFieldGet(this, _cache)[key] = {
                        data: JSON.parse(JSON.stringify(data)),
                        createdOn: new Date(),
                    };
                }
                try {
                    yield ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.set(key, __classPrivateFieldGet(this, _cache)[key]));
                    __classPrivateFieldGet(this, _subject)[key].next(__classPrivateFieldGet(this, _cache)[key].data);
                }
                catch (err) {
                    console.error(err);
                }
            });
        });
        _has.set(this, (key, option) => {
            return () => {
                let cache = __classPrivateFieldGet(this, _cache)[key];
                if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                    try {
                        cache = JSON.parse(sessionStorage.getItem(key));
                    }
                    catch (_a) {
                        cache = undefined;
                    }
                }
                else {
                    try {
                        cache = JSON.parse(localStorage.getItem(key));
                    }
                    catch (_b) {
                        cache = undefined;
                    }
                }
                if (!cache) {
                    return false;
                }
                return true;
            };
        });
        _hasServer.set(this, (key, option) => {
            return () => __awaiter(this, void 0, void 0, function* () {
                var _a;
                let cache = __classPrivateFieldGet(this, _cache)[key];
                try {
                    cache = yield ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.get(key, option));
                }
                catch (_b) {
                    cache = undefined;
                }
                if (!cache) {
                    return false;
                }
                return true;
            });
        });
        _remove.set(this, (key, option) => {
            return () => __awaiter(this, void 0, void 0, function* () {
                try {
                    if ((option === null || option === void 0 ? void 0 : option.type) === 'session') {
                        sessionStorage.removeItem(key);
                    }
                    else {
                        localStorage.removeItem(key);
                    }
                    __classPrivateFieldGet(this, _cache)[key] = undefined;
                    __classPrivateFieldGet(this, _subject)[key].next(undefined);
                }
                catch (err) {
                    console.error(err);
                }
            });
        });
        _removeServer.set(this, (key, option) => {
            return () => __awaiter(this, void 0, void 0, function* () {
                var _a;
                try {
                    yield ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.remove(key, option));
                    __classPrivateFieldGet(this, _cache)[key] = undefined;
                    __classPrivateFieldGet(this, _subject)[key].next(undefined);
                }
                catch (err) {
                    console.error(err);
                }
            });
        });
    }
    create(key, option) {
        var _a;
        if (!key) {
            throw new Error('Key is required');
        }
        let hashKey = null;
        if (typeof key === 'string') {
            hashKey = key;
        }
        else if (typeof key === 'object') {
            hashKey = hash(key);
        }
        else {
            throw new Error('Invalid key');
        }
        if ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.convertKey) {
            hashKey = this.configuration.convertKey(hashKey);
        }
        const get = __classPrivateFieldGet(this, _get).call(this, hashKey, option);
        const set = __classPrivateFieldGet(this, _set).call(this, hashKey, option);
        const has = __classPrivateFieldGet(this, _has).call(this, hashKey, option);
        const remove = __classPrivateFieldGet(this, _remove).call(this, hashKey, option);
        if (!__classPrivateFieldGet(this, _subject)[hashKey]) {
            __classPrivateFieldGet(this, _subject)[hashKey] = new BehaviorSubject(get());
            __classPrivateFieldGet(this, _observer)[hashKey] = __classPrivateFieldGet(this, _subject)[hashKey].asObservable();
        }
        return {
            get,
            set,
            has,
            remove,
            subject: __classPrivateFieldGet(this, _subject)[hashKey],
            observer: __classPrivateFieldGet(this, _observer)[hashKey],
        };
    }
    createServer(key, option) {
        var _a, _b, _c, _d;
        if (!key) {
            throw new Error('Key is required');
        }
        let hashKey = null;
        if (typeof key === 'string') {
            hashKey = key;
        }
        else if (typeof key === 'object') {
            hashKey = hash(key);
        }
        else {
            throw new Error('Invalid key');
        }
        if ((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.convertKey) {
            hashKey = this.configuration.convertKey(hashKey);
        }
        if (!((_b = this.configuration) === null || _b === void 0 ? void 0 : _b.get)) {
            throw new Error('Please init setting configuration method get for type server');
        }
        if (!((_c = this.configuration) === null || _c === void 0 ? void 0 : _c.set)) {
            throw new Error('Please init setting configuration method set for type server');
        }
        if (!((_d = this.configuration) === null || _d === void 0 ? void 0 : _d.remove)) {
            throw new Error('Please init setting configuration method remove for type server');
        }
        if (!__classPrivateFieldGet(this, _subject)[hashKey]) {
            __classPrivateFieldGet(this, _subject)[hashKey] = new BehaviorSubject(option === null || option === void 0 ? void 0 : option.default);
        }
        const get = __classPrivateFieldGet(this, _getServer).call(this, hashKey, option);
        const set = __classPrivateFieldGet(this, _setServer).call(this, hashKey, option);
        const has = __classPrivateFieldGet(this, _hasServer).call(this, hashKey, option);
        const remove = __classPrivateFieldGet(this, _remove).call(this, hashKey, option);
        return {
            get,
            set,
            has,
            remove,
            subject: __classPrivateFieldGet(this, _subject)[hashKey],
            observer: __classPrivateFieldGet(this, _subject)[hashKey].pipe(startWith(__classPrivateFieldGet(this, _subject)[hashKey].getValue()), switchMap(get)),
        };
    }
}
_cache = new WeakMap(), _subject = new WeakMap(), _observer = new WeakMap(), _get = new WeakMap(), _getServer = new WeakMap(), _set = new WeakMap(), _setServer = new WeakMap(), _has = new WeakMap(), _hasServer = new WeakMap(), _remove = new WeakMap(), _removeServer = new WeakMap();
SdSettingService.ɵprov = ɵɵdefineInjectable({ factory: function SdSettingService_Factory() { return new SdSettingService(ɵɵinject(SETTING_CONFIG, 8)); }, token: SdSettingService, providedIn: "root" });
SdSettingService.decorators = [
    { type: Injectable, args: [{
                providedIn: 'root',
            },] }
];
SdSettingService.ctorParameters = () => [
    { type: undefined, decorators: [{ type: Inject, args: [SETTING_CONFIG,] }, { type: Optional }] }
];

/*
 * Public API Surface of superdev-angular-core
 */

/**
 * Generated bundle index. Do not edit.
 */

export { SETTING_CONFIG, SdSettingService };
//# sourceMappingURL=sd-angular-core-setting.js.map
