import { assertExists, DisposableGroup } from '@blockeditor/global/utils';
import { createLitPortal } from '../portal.js';
import { whenHover } from './when-hover.js';
const DEFAULT_HOVER_OPTIONS = {
    transition: {
        in: {
            opacity: '1',
            transition: 'opacity 0.1s ease-in-out',
        },
        out: {
            opacity: '0',
            transition: 'opacity 0.1s ease-in-out',
        },
    },
    setPortalAsFloating: true,
};
export class HoverController {
    get setReference() {
        if (!this._setReference) {
            throw new Error('setReference is not ready');
        }
        return this._setReference;
    }
    get portal() {
        return this._portal;
    }
    constructor(host, onHover, hoverOptions) {
        this._disposables = new DisposableGroup();
        (this.host = host).addController(this);
        this._onHover = onHover;
        this._hoverOptions = { ...DEFAULT_HOVER_OPTIONS, ...hoverOptions };
    }
    hostConnected() {
        if (this._disposables.disposed) {
            this._disposables = new DisposableGroup();
        }
        // Start a timer when the host is connected
        const { setReference, setFloating, dispose } = whenHover(isHover => {
            if (!isHover) {
                const abortController = this._abortController;
                if (!abortController)
                    return;
                if (!this._portal || !this._hoverOptions.transition) {
                    abortController.abort();
                    return;
                }
                // Transition out
                Object.assign(this._portal.style, this._hoverOptions.transition.out);
                this._portal.addEventListener('transitionend', () => {
                    abortController.abort();
                }, { signal: abortController.signal });
                return;
            }
            if (this._abortController)
                return;
            this._abortController = new AbortController();
            this._abortController.signal.addEventListener('abort', () => {
                this._abortController = undefined;
            });
            const portalOptions = this._onHover({
                setReference,
                abortController: this._abortController,
            });
            if (!portalOptions) {
                this._abortController.abort();
                return;
            }
            this._portal = createLitPortal({
                ...portalOptions,
                abortController: this._abortController,
            });
            const transition = this._hoverOptions.transition;
            if (transition) {
                Object.assign(this._portal.style, transition.out);
                setTimeout(() => {
                    assertExists(this._portal);
                    Object.assign(this._portal.style, transition.in);
                });
            }
            if (this._hoverOptions.setPortalAsFloating) {
                setFloating(this._portal);
            }
        }, this._hoverOptions);
        this._setReference = setReference;
        this._disposables.add(dispose);
    }
    hostDisconnected() {
        this._abortController?.abort();
        this._disposables.dispose();
    }
}
//# sourceMappingURL=controller.js.map