/*!
 * Custom elements for Nanopore-Digital Web applications
 */
/**
 * Quality of life for transition handling.
 * Adds / removes transitionend events. Resolves on complete

 * @param el element
 * @returns a promise that resolves when the transition is done
 */
export const transitionDone = (el) => {
    return new Promise((resolve) => {
        const callback = () => {
            el.removeEventListener('transitionend', callback);
            resolve(void 0);
        };
        el.addEventListener('transitionend', callback);
    });
};
/**
 * handles hiding and showing elements properly (with display),
 * along with transitions, so they are no longer viewable in the dom.
 * - OnHide remove show class, listen for transition end, then display: none on finish
 * - OnShow, display block on start then add a show class
 *
 * @param el
 * @param options
 * @returns a promise of resolving as either 'show' or 'hidden'
 */
export const displayTransition = (el, options) => {
    const opts = {
        className: '',
        show: true,
        showDisplay: 'block',
        showProp: 'classList',
        timeout: 1000,
        ...options,
    };
    return new Promise((resolve) => {
        const showCb = (e) => {
            if ((e.target === el || e.composedPath().some((el) => el === e.target)) &&
                (!opts.transitionProp || opts.transitionProp.includes(e.propertyName))) {
                el.dataset.displayTransition = 'true';
                el.removeEventListener('transitionend', showCb);
                resolve('shown');
            }
        };
        const hideCb = (e) => {
            if ((e.target === el || e.composedPath().some((el) => el === e.target)) &&
                (!opts.transitionProp || opts.transitionProp.includes(e.propertyName))) {
                el.style.display = 'none';
                el.dataset.displayTransition = 'false';
                el.removeEventListener('transitionend', hideCb);
                resolve('hidden');
            }
        };
        if (opts.show) {
            el.addEventListener('transitionend', showCb);
            el.style.display = opts.showDisplay;
            // eslint-disable-next-line @typescript-eslint/no-unused-expressions
            el.clientWidth; // force reflow
            setTimeout(() => el[opts.showProp].add(opts.className), 50);
        }
        else {
            el.addEventListener('transitionend', hideCb);
            el[opts.showProp].remove(opts.className);
        }
        // If no transition, resolve after timeout
        if (opts.timeout) {
            setTimeout(() => {
                if (opts.show && el.dataset.displayTransition !== 'true') {
                    el.dataset.displayTransition = 'true';
                    el.removeEventListener('transitionend', showCb);
                    resolve('shown');
                }
                else if (!opts.show && el.dataset.displayTransition !== 'false') {
                    el.style.display = 'none';
                    el.dataset.displayTransition = 'false';
                    el.removeEventListener('transitionend', hideCb);
                    resolve('hidden');
                }
            }, opts.timeout);
        }
    });
};
