// #region Imports
import { DomServiceLocator } from '../../Dom/Dom';
import { ControllerBase } from './Abstracts/ControllerBase';
/**
 * IntersectionAnchorController - This controller is used to observe the intersection of an element with the top and bottom of the viewport.
 *
 * @public
 */
export class IntersectionAnchorController extends ControllerBase {
    // #region Properties
    _observer;
    _anchor;
    _callback;
    // #endregion
    // #region Ctor
    constructor(host, config) {
        super(host);
        this._anchor = config.anchor ?? {};
        this._callback = config.callback;
        this._observer = new IntersectionObserver((entries) => {
            this.handleChanges(entries);
            this.host.requestUpdate();
        }, {
            ...config.config,
            root: this.tryGetElement(config.target) ?? host
        });
    }
    // #endregion
    // #region Methods
    /**
     * @public
     * @override
     */
    hostConnected() {
        if (this._anchor.top) {
            const topAnchor = this.tryGetElement(this._anchor.top);
            if (topAnchor) {
                this._observer.observe(topAnchor);
            }
        }
        if (this._anchor.bottom) {
            const bottomAnchor = this.tryGetElement(this._anchor.bottom);
            if (bottomAnchor) {
                this._observer.observe(bottomAnchor);
            }
        }
    }
    /**
     * @public
     * @override
     */
    hostDisconnected() {
        this.disconnect();
    }
    /**
     * @public
     */
    disconnect() {
        this._observer.disconnect();
    }
    /**
     * @public
     */
    handleChanges(entries) {
        const anchor = {
            isAtScrollTop: false,
            isAtScrollBottom: false
        };
        for (const entry of entries) {
            if (entry.target === this._anchor.top) {
                anchor.isAtScrollTop = entry.isIntersecting;
            }
            if (entry.target === this._anchor.bottom) {
                anchor.isAtScrollBottom = entry.isIntersecting;
            }
        }
        this._callback?.(anchor);
    }
    tryGetElement(elementOrSelector) {
        if (typeof elementOrSelector === 'string') {
            return DomServiceLocator.current.findDescendant(this.host, elementOrSelector);
        }
        return elementOrSelector ?? null;
    }
}
//# sourceMappingURL=IntersectionAnchorController.js.map