// #region Imports
import { on } from '@breadstone/mosaik-elements';
import { Timer } from '../../Dom/Timer';
import { ControllerBase } from './Abstracts/ControllerBase';
/**
 * AutoplayController - Manages timer-based autoplay with pause/resume on hover.
 *
 * Provides a reusable controller for components that need:
 * - Automatic periodic action (timer tick)
 * - Pause on pointer enter / resume on pointer leave
 * - Dynamic timeout duration
 * - Proper lifecycle cleanup
 *
 * Used by: ToastElement, CarouselElement, and similar components.
 *
 * @example
 * ```typescript
 * private readonly _autoplayController = new AutoplayController(this, {
 *   onTimerTick: () => this.selectNext(),
 *   getDuration: () => this.timeout,
 *   getHoverElement: () => this.getTemplatePart('content'),
 *   isEnabled: () => this.autoplay && this.timeout > 0
 * });
 *
 * // Public API
 * public start(): void { this._autoplayController.start(); }
 * public stop(): void { this._autoplayController.stop(); }
 * public pause(): void { this._autoplayController.pause(); }
 * public resume(): void { this._autoplayController.resume(); }
 * ```
 *
 * @public
 */
export class AutoplayController extends ControllerBase {
    // #region Fields
    _config;
    _timer;
    _pointerEnterSubscription;
    _pointerLeaveSubscription;
    _hoverElement;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the `AutoplayController` class.
     *
     * @public
     */
    constructor(host, config) {
        super(host);
        this._config = config;
        this._timer = Timer.empty(() => {
            if (this._config.isEnabled()) {
                this._config.onTimerTick();
            }
        });
        this._pointerEnterSubscription = null;
        this._pointerLeaveSubscription = null;
        this._hoverElement = null;
    }
    // #endregion
    // #region Lifecycle
    /**
     * @public
     * @override
     */
    hostDisconnected() {
        super.hostDisconnected();
        this.stop();
    }
    // #endregion
    // #region Public API
    /**
     * Starts the autoplay timer.
     * Only starts if `isEnabled()` returns true and duration > 0.
     *
     * @public
     */
    start() {
        if (!this._config.isEnabled()) {
            return;
        }
        const duration = this._config.getDuration();
        if (duration <= 0) {
            return;
        }
        this._timer.setDuration(duration);
        this._timer.start();
        this.attachHoverListener();
    }
    /**
     * Stops the autoplay timer and cleans up hover listeners.
     *
     * @public
     */
    stop() {
        this._timer.destroy();
        this.detachHoverListener();
    }
    /**
     * Pauses the autoplay timer (suspends countdown, preserves remaining time).
     *
     * @public
     */
    pause() {
        this._timer.pause();
    }
    /**
     * Resumes the autoplay timer (resumes countdown from where it was paused).
     *
     * @public
     */
    resume() {
        this._timer.resume();
    }
    /**
     * Updates the timer duration and restarts with the new value.
     * Used when component state changes duration dynamically (e.g., Carousel item timeout override).
     *
     * @public
     * @param newDuration - New duration in milliseconds.
     */
    updateDurationAndRestart(newDuration) {
        if (newDuration <= 0) {
            this.stop();
            return;
        }
        this._timer.setDuration(newDuration);
        this._timer.restart();
    }
    // #endregion
    // #region Private Methods
    /**
     * Attaches hover listeners (pointerenter/pointerleave) to pause/resume the timer.
     *
     * @private
     */
    attachHoverListener() {
        if (this._pointerEnterSubscription) {
            return; // Already attached
        }
        const element = this._config.getHoverElement?.();
        if (!element) {
            return; // No hover element configured
        }
        this._hoverElement = element;
        this._pointerEnterSubscription = on(element, 'pointerenter', () => this.pause(), { passive: true });
        this._pointerLeaveSubscription = on(element, 'pointerleave', () => this.resume(), { passive: true });
    }
    /**
     * Detaches hover listeners and cleans up subscriptions.
     *
     * @private
     */
    detachHoverListener() {
        this._pointerEnterSubscription?.dispose();
        this._pointerLeaveSubscription?.dispose();
        this._pointerEnterSubscription = null;
        this._pointerLeaveSubscription = null;
        this._hoverElement = null;
    }
}
/**
 * Factory function to add an `AutoplayController` to a host element.
 *
 * @public
 * @param host - The controller host element.
 * @param config - The autoplay configuration.
 * @returns The created controller instance.
 */
export function addAutoplayController(host, config) {
    return new AutoplayController(host, config);
}
//# sourceMappingURL=AutoplayController.js.map