// #region Imports
import { query } from '../../Controls/Directives/Query';
/**
 * A method decorator that listens to a specific event on a target element.
 *
 * @example
 * ```typescript
 * class MyElement extends HTMLElement {
 *    @Listen('click', 'self', { preventDefault: true })
 *    handleClick(event: MouseEvent) {
 *        console.log('Element clicked!', event);
 *   }
 * }
 * ```
 *
 * @public
 */
export function Listen(eventName, target = 'self', options) {
    return (prototype, methodName) => {
        const originalConnectedCallback = prototype.connectedCallback;
        const originalDisconnectedCallback = prototype.disconnectedCallback;
        prototype.connectedCallback = function () {
            let actualTarget = null;
            if (target === 'self') {
                actualTarget = this;
            }
            else if (target === 'window') {
                actualTarget = window;
            }
            else if (target === 'document') {
                actualTarget = document;
            }
            else if (typeof target === 'object') {
                actualTarget = query(this, target.selector);
            }
            const handler = (event) => {
                if (options?.preventDefault) {
                    event.preventDefault();
                }
                this[methodName](event);
            };
            actualTarget?.addEventListener(eventName, handler, options);
            if (originalConnectedCallback) {
                originalConnectedCallback.call(this);
            }
            this[`__${methodName}_handler`] = handler;
            this[`__${methodName}_actualTarget`] = actualTarget;
        };
        prototype.disconnectedCallback = function () {
            let actualTarget = null;
            if (this[`__${methodName}_actualTarget`]) {
                actualTarget = this[`__${methodName}_actualTarget`];
            }
            else if (target === 'self') {
                actualTarget = this;
            }
            else if (target === 'window') {
                actualTarget = window;
            }
            else if (target === 'document') {
                actualTarget = document;
            }
            else if (typeof target === 'string') {
                actualTarget = document.querySelector(target);
            }
            else {
                actualTarget = this;
            }
            if (actualTarget) {
                actualTarget.removeEventListener(eventName, this[`__${methodName}_handler`]);
            }
            if (originalDisconnectedCallback) {
                originalDisconnectedCallback.call(this);
            }
        };
    };
}
//# sourceMappingURL=ListenDecorator.js.map