const fakeStorage = {
    _data: {},
    /**
     * Get fake storage value from key identifier
     *
     * @param key
     * @returns
     */
    getItem: (key) => {
        if (Object.prototype.hasOwnProperty.call(fakeStorage._data, key)) {
            return fakeStorage._data[key];
        }
        return null;
    },
    /**
     * Set value to fake storage from key identifier
     *
     * @param key
     * @param obj
     */
    setItem: (key, obj) => {
        fakeStorage._data[key] = obj;
    },
    /**
     * Remove fake storage from key identifier
     *
     * @param key
     */
    removeItem: (key) => {
        if (Object.prototype.hasOwnProperty.call(fakeStorage._data, key)) {
            delete fakeStorage._data[key];
        }
    },
};
const getStorage = () => {
    try {
        return window.localStorage;
    }
    catch (err) {
        return fakeStorage;
    }
};
const OJSON = window.JSON;
const storage = getStorage();
const StorageService = {
    /**
     * Get storage value from key identifier
     *
     * @param key
     * @returns
     */
    get(key) {
        let value = storage.getItem(key);
        if (/^\{.*\}$/.test(value)) {
            value = OJSON.parse(value);
        }
        return value;
    },
    /**
     * Set value to storage from key identifier
     *
     * @param key
     * @param value
     * @returns
     */
    set(key, value) {
        if (typeof value === typeof {}) {
            value = OJSON.stringify(value);
        }
        return storage.setItem(key, value);
    },
    /**
     * Remove storage from key identifier
     *
     * @param key
     * @returns
     */
    remove(key) {
        return storage.removeItem(key);
    },
};
const create = () => Object.assign((key, value) => StorageService.set(key, value), StorageService);
const Store = create();

const themeModeStorageKey = 'ui.theme.mode';
const breakpoints = {
    sm: 576,
    md: 768,
    lg: 992,
    xl: 1200,
};
class ThemeService {
    /**
     * Init service
     *
     * @param mode
     */
    constructor(mode = 'light') {
        this.mode = mode;
        /**
         * Window width size
         */
        this.width = 0;
        /**
         * Window height size
         */
        this.height = 0;
        /**
         * Bootstrap breakpoint size
         */
        this.size = 'xs';
        if (Store.get(themeModeStorageKey)) {
            this.switch(Store.get(themeModeStorageKey));
        }
        else {
            this.autodetectTheme();
        }
        this.setupSizes(window.innerWidth, window.innerHeight);
        window.addEventListener('resize', () => {
            this.setupSizes(window.innerWidth, window.innerHeight);
        });
    }
    /**
     * Toggle theme type between `light` & `dark`
     */
    toggle() {
        this.switch(this.mode === 'dark' ? 'light' : 'dark');
    }
    /**
     * Validate if modal is open
     */
    validateModals() {
        if (typeof document !== 'undefined') {
            setTimeout(() => {
                const modalsOpen = Boolean(document.querySelector('x-overlay-container x-modal.modal-show'));
                if (modalsOpen) {
                    document.querySelector("body").classList.add("modal-open");
                }
                else {
                    document.querySelector("body").classList.remove("modal-open");
                }
            }, 100);
        }
    }
    /**
     * Verify if size types is actual size
     *
     * @param sizes
     * @returns
     */
    is(...sizes) {
        if (Array.isArray(sizes)) {
            return sizes.includes(this.size);
        }
        return false;
    }
    /**
     * Get actual theme
     *
     * @returns
     */
    getTheme() {
        return this.mode;
    }
    /**
     * Detect browser|device|user actual theme
     */
    autodetectTheme() {
        this.switch(window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? 'dark' : 'light');
    }
    /**
     * Init and discover breakpoint sizes
     *
     * @param width
     * @param height
     */
    setupSizes(width, height) {
        this.width = width;
        this.height = height;
        this.size = this.getSizeByWidth(width);
    }
    /**
     * Get the bootstrap size key by window size
     *
     * @param width
     * @returns
     */
    getSizeByWidth(width) {
        if (width >= breakpoints.xl) {
            return 'xl';
        }
        if (width >= breakpoints.lg) {
            return 'lg';
        }
        if (width >= breakpoints.md) {
            return 'md';
        }
        if (width >= breakpoints.sm) {
            return 'sm';
        }
        return 'xs';
    }
    /**
     * Change actual theme
     *
     * @param theme
     */
    switch(theme) {
        if (theme == "dark" && document) {
            this.mode = theme;
            document.querySelector("body").classList.add("is-dark-mode");
            Store.set(themeModeStorageKey, theme);
        }
        if (theme == "light" && document) {
            this.mode = theme;
            document.querySelector("body").classList.remove("is-dark-mode");
            Store.set(themeModeStorageKey, theme);
        }
    }
    /**
     * Create service
     *
     * @returns
     */
    static create() {
        const instance = new ThemeService();
        return Object.assign((theme) => instance.switch(theme), {
            toggle: () => instance.toggle(),
            validateModals: () => instance.validateModals(),
            is: (...sizes) => instance.is(...sizes),
            getTheme: () => instance.getTheme(),
            autodetectTheme: () => instance.autodetectTheme(),
            size: instance.size,
        });
    }
}
const Theme = ThemeService.create();
const Query = (name, parent) => (parent || document).querySelector(`[ref="${name}"]`);

export { Query as Q, Store as S, Theme as T };
