import { __assign, __extends } from "tslib";
import { v4 as uuid } from '@lukeed/uuid';
import jar from 'js-cookie';
import { tld } from './tld';
import autoBind from '../../lib/bind-all';
var defaults = {
    persist: true,
    cookie: {
        key: 'ajs_user_id',
        oldKey: 'ajs_user',
    },
    localStorage: {
        key: 'ajs_user_traits',
    },
};
var Store = /** @class */ (function () {
    function Store() {
        this.cache = {};
    }
    Store.prototype.get = function (key) {
        return this.cache[key];
    };
    Store.prototype.set = function (key, value) {
        this.cache[key] = value;
        return value;
    };
    Store.prototype.remove = function (key) {
        delete this.cache[key];
    };
    return Store;
}());
var domain = undefined;
try {
    domain = tld(new URL(window.location.href));
}
catch (_) {
    domain = undefined;
}
var ONE_YEAR = 365;
var Cookie = /** @class */ (function (_super) {
    __extends(Cookie, _super);
    function Cookie(options) {
        if (options === void 0) { options = Cookie.defaults; }
        var _this = _super.call(this) || this;
        _this.options = __assign(__assign({}, Cookie.defaults), options);
        return _this;
    }
    Cookie.available = function () {
        var cookieEnabled = window.navigator.cookieEnabled;
        if (!cookieEnabled) {
            jar.set('ajs:cookies', 'test');
            cookieEnabled = document.cookie.includes('ajs:cookies');
            jar.remove('ajs:cookies');
        }
        return cookieEnabled;
    };
    Cookie.prototype.opts = function () {
        return {
            sameSite: this.options.sameSite,
            expires: this.options.maxage,
            domain: this.options.domain,
            path: this.options.path,
        };
    };
    Cookie.prototype.get = function (key) {
        return jar.getJSON(key);
    };
    Cookie.prototype.set = function (key, value) {
        if (typeof value === 'string') {
            jar.set(key, value, this.opts());
        }
        else if (value === null) {
            jar.remove(key, this.opts());
        }
        else {
            jar.set(key, JSON.stringify(value), this.opts());
        }
        return value;
    };
    Cookie.prototype.remove = function (key) {
        return jar.remove(key, this.opts());
    };
    Cookie.defaults = {
        maxage: ONE_YEAR,
        domain: domain,
        path: '/',
        sameSite: 'Lax',
    };
    return Cookie;
}(Store));
export { Cookie };
var NullStorage = /** @class */ (function (_super) {
    __extends(NullStorage, _super);
    function NullStorage() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.get = function (_key) { return null; };
        _this.set = function (_key, _val) { return null; };
        _this.remove = function (_key) { };
        return _this;
    }
    return NullStorage;
}(Store));
var LocalStorage = /** @class */ (function (_super) {
    __extends(LocalStorage, _super);
    function LocalStorage() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    LocalStorage.available = function () {
        var test = 'test';
        try {
            localStorage.setItem(test, test);
            localStorage.removeItem(test);
            return true;
        }
        catch (e) {
            return false;
        }
    };
    LocalStorage.prototype.get = function (key) {
        var val = localStorage.getItem(key);
        return val ? JSON.parse(val) : null;
    };
    LocalStorage.prototype.set = function (key, value) {
        localStorage.setItem(key, JSON.stringify(value));
        return value;
    };
    LocalStorage.prototype.remove = function (key) {
        return localStorage.removeItem(key);
    };
    return LocalStorage;
}(Store));
export { LocalStorage };
var User = /** @class */ (function () {
    function User(options, cookieOptions) {
        var _this = this;
        if (options === void 0) { options = defaults; }
        var _a, _b, _c, _d;
        this.mem = new Store();
        this.options = {};
        this.id = function (id) {
            var _a, _b;
            var prevId = _this.chainGet(_this.idKey);
            if (id !== undefined) {
                _this.trySet(_this.idKey, id);
                var changingIdentity = id !== prevId && prevId !== null && id !== null;
                if (changingIdentity) {
                    _this.anonymousId(null);
                }
            }
            return ((_b = (_a = _this.chainGet(_this.idKey)) !== null && _a !== void 0 ? _a : _this.cookies.get(defaults.cookie.oldKey)) !== null && _b !== void 0 ? _b : null);
        };
        this.anonymousId = function (id) {
            var _a, _b;
            if (id === undefined) {
                var val = (_a = _this.chainGet(_this.anonKey)) !== null && _a !== void 0 ? _a : (_b = _this.legacySIO()) === null || _b === void 0 ? void 0 : _b[0];
                if (val) {
                    return val;
                }
            }
            if (id === null) {
                _this.trySet(_this.anonKey, null);
                return _this.chainGet(_this.anonKey);
            }
            _this.trySet(_this.anonKey, id !== null && id !== void 0 ? id : uuid());
            return _this.chainGet(_this.anonKey);
        };
        this.traits = function (traits) {
            var _a, _b;
            if (traits === null) {
                traits = {};
            }
            if (traits) {
                _this.mem.set(_this.traitsKey, traits !== null && traits !== void 0 ? traits : {});
                _this.localStorage.set(_this.traitsKey, traits !== null && traits !== void 0 ? traits : {});
            }
            return ((_b = (_a = _this.localStorage.get(_this.traitsKey)) !== null && _a !== void 0 ? _a : _this.mem.get(_this.traitsKey)) !== null && _b !== void 0 ? _b : {});
        };
        this.options = options;
        this.idKey = (_b = (_a = options.cookie) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : defaults.cookie.key;
        this.traitsKey = (_d = (_c = options.localStorage) === null || _c === void 0 ? void 0 : _c.key) !== null && _d !== void 0 ? _d : defaults.localStorage.key;
        this.anonKey = 'ajs_anonymous_id';
        var shouldPersist = options.persist !== false;
        this.localStorage =
            options.localStorageFallbackDisabled ||
                !shouldPersist ||
                !LocalStorage.available()
                ? new NullStorage()
                : new LocalStorage();
        this.cookies =
            shouldPersist && Cookie.available()
                ? new Cookie(cookieOptions)
                : new NullStorage();
        var legacyUser = this.cookies.get(defaults.cookie.oldKey);
        if (legacyUser) {
            legacyUser.id && this.id(legacyUser.id);
            legacyUser.traits && this.traits(legacyUser.traits);
        }
        autoBind(this);
    }
    User.prototype.chainGet = function (key) {
        var _a, _b, _c;
        var val = (_c = (_b = (_a = this.localStorage.get(key)) !== null && _a !== void 0 ? _a : this.cookies.get(key)) !== null && _b !== void 0 ? _b : this.mem.get(key)) !== null && _c !== void 0 ? _c : null;
        return this.trySet(key, typeof val === 'number' ? val.toString() : val);
    };
    User.prototype.trySet = function (key, value) {
        this.localStorage.set(key, value);
        this.cookies.set(key, value);
        this.mem.set(key, value);
        return value;
    };
    User.prototype.chainClear = function (key) {
        this.localStorage.remove(key);
        this.cookies.remove(key);
        this.mem.remove(key);
    };
    User.prototype.legacySIO = function () {
        var val = this.cookies.get('_sio');
        if (!val) {
            return null;
        }
        var _a = val.split('----'), anon = _a[0], user = _a[1];
        return [anon, user];
    };
    User.prototype.identify = function (id, traits) {
        traits = traits !== null && traits !== void 0 ? traits : {};
        var currentId = this.id();
        if (currentId === null || currentId === id) {
            traits = __assign(__assign({}, this.traits()), traits);
        }
        if (id) {
            this.id(id);
        }
        this.traits(traits);
    };
    User.prototype.logout = function () {
        this.anonymousId(null);
        this.id(null);
        this.traits({});
    };
    User.prototype.reset = function () {
        this.logout();
        this.chainClear(this.idKey);
        this.chainClear(this.anonKey);
        this.chainClear(this.traitsKey);
    };
    User.prototype.load = function () {
        return new User(this.options);
    };
    User.prototype.save = function () {
        return true;
    };
    User.defaults = defaults;
    return User;
}());
export { User };
var groupDefaults = {
    persist: true,
    cookie: {
        key: 'ajs_group_id',
    },
    localStorage: {
        key: 'ajs_group_properties',
    },
};
var Group = /** @class */ (function (_super) {
    __extends(Group, _super);
    function Group(options, cookie) {
        if (options === void 0) { options = groupDefaults; }
        var _this = _super.call(this, options, cookie) || this;
        _this.anonymousId = function (_id) {
            return undefined;
        };
        autoBind(_this);
        return _this;
    }
    return Group;
}(User));
export { Group };
//# sourceMappingURL=index.js.map