// #region Imports
import { StorageServiceLocator } from '../Storage';
/**
 * @public
 */
export function Persisted(config = {}) {
    return (target, propertyKey) => {
        const storageKey = config.storageKey ?? propertyKey;
        const originalDescriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
        const updateFromLocalStorage = function updateFromLocalStorage() {
            const storedValue = JSON.parse(localStorage.getItem(storageKey));
            if (storedValue !== null && storedValue !== this[propertyKey]) {
                this[propertyKey] = storedValue;
            }
        };
        window.addEventListener('storage', (event) => {
            if (event.key === storageKey) {
                updateFromLocalStorage.call(target);
            }
        });
        if (originalDescriptor && (originalDescriptor.get ?? originalDescriptor.set)) {
            // If property has getter and setter
            const originalGetter = originalDescriptor.get;
            const originalSetter = originalDescriptor.set;
            // Enhance the original descriptor with our custom logic
            originalDescriptor.get = function get() {
                if (StorageServiceLocator.current.has(storageKey)) {
                    const storageValue = StorageServiceLocator.current.get(storageKey);
                    // set the value to the original property
                    // important: if the property is modified in the original setter, this has no effect here
                    originalSetter?.call(this, storageValue);
                    return storageValue;
                }
                return originalGetter?.call(this);
            };
            originalDescriptor.set = function set(newVal) {
                StorageServiceLocator.current.set(storageKey, newVal);
                originalSetter?.call(this, newVal);
            };
            return originalDescriptor;
        }
        // If it's a simple field
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        let val = target[propertyKey] || config.defaultValue;
        function getter() {
            return StorageServiceLocator.current.get(storageKey);
        }
        const setter = (newVal) => {
            val = newVal;
            StorageServiceLocator.current.set(storageKey, newVal);
        };
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
        if (delete target[propertyKey]) {
            Object.defineProperty(target, propertyKey, {
                get: getter,
                set: setter,
                enumerable: true,
                configurable: true
            });
        }
    };
}
//# sourceMappingURL=PersistedDecorator.js.map