import { jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useState, useCallback, forwardRef } from 'react';
import styled, { css } from 'styled-components';
import { defaultThemeProp } from '../../theme';
import { reflow, withTestIds } from '../../utils';
import Configuration from '../Configuration';
import Flex from '../Flex';
import { useConsolidatedRef, useElement, useTestIds } from '../../hooks';
import { getBackdropTestIds } from './Backdrop.test-ids';
const transitionSpeedToTheme = {
    slow: 2,
    medium: 1,
    fast: 0.5,
    none: 0
};
export const StyledBackdrop = styled(Flex)(props => {
    const { theme: { base } } = props;
    const { opacity, alpha, variant, position } = props;
    const transitionDuration = `max(calc(${transitionSpeedToTheme[props.transitionSpeed]} * ${base.animation.speed}), 1ms)`;
    return css `
      position: ${position};
      z-index: ${position === 'fixed' ? base['z-index'].backdrop : base['z-index'].popover + 1};
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      border-radius: inherit;
      opacity: ${opacity};
      transition-property: opacity;
      transition-timing-function: ${props.theme.base.animation.timing.ease};
      /* stylelint-disable declaration-block-no-duplicate-properties */
      transition-duration: 1ms;
      transition-duration: ${transitionDuration};
      /* stylelint-enable declaration-block-no-duplicate-properties */

      ${variant === 'dark' &&
        css `
        background: rgba(0, 0, 0, ${alpha});
      `}

      ${variant === 'light' &&
        css `
        background: rgba(255, 255, 255, ${alpha});
      `}
    `;
});
StyledBackdrop.defaultProps = defaultThemeProp;
export default withTestIds(forwardRef(function Backdrop({ testId, children, container, open = false, variant = 'dark', transitionSpeed = 'medium', alpha = 0.6, position = 'fixed', onBeforeTransitionIn, onAfterTransitionIn, onBeforeTransitionOut, onAfterTransitionOut, ...restProps }, ref) {
    const testIds = useTestIds(testId, getBackdropTestIds);
    const [state, setState] = useState('closed');
    const [backdropEl, setBackdropEl] = useElement();
    const backdropRef = useConsolidatedRef(ref, setBackdropEl);
    const onTransitionEnd = useCallback((e) => {
        if (e.propertyName !== 'opacity' || e.target !== e.currentTarget)
            return;
        let nextState;
        if (state === 'closing') {
            nextState = 'closed';
            onAfterTransitionOut?.();
        }
        else {
            nextState = 'open';
            onAfterTransitionIn?.();
        }
        setState(nextState);
    }, [state, onAfterTransitionOut, onAfterTransitionIn]);
    useEffect(() => {
        if (open) {
            if (state === 'closed' || state === 'closing') {
                onBeforeTransitionIn?.();
                reflow();
                setState('opening');
            }
        }
        else if (state === 'open' || state === 'opening') {
            onBeforeTransitionOut?.();
            setState('closing');
        }
    }, [open]);
    // Using a separate effect instead of combined logic above as it seems more intuitive to mentally manage.
    useEffect(() => {
        if (!backdropRef.current)
            return;
        const opacity = window.getComputedStyle(backdropRef.current).opacity;
        // If the opacity is already at the destination value, sync the state value.
        if (state === 'closing' && opacity === '0') {
            // Since the transition never ran, we have to pretend it did and call the callback.
            // TODO: This maybe can be fixed with the animation api
            onAfterTransitionOut?.();
            setState('closed');
        }
        if (state === 'opening' && opacity === '1') {
            // ditto, see above...
            onAfterTransitionIn?.();
            setState('open');
        }
    }, [state]);
    return !open && state === 'closed' ? null : (_jsx(Configuration, { portalTarget: backdropEl ?? undefined, children: _jsx(StyledBackdrop, { "data-testid": testIds.root, container: { justify: 'center', alignItems: 'center', ...container }, transitionSpeed: transitionSpeed, opacity: state === 'opening' || state === 'open' ? 1 : 0, alpha: alpha, variant: variant, position: position, onTransitionEnd: onTransitionEnd, ref: backdropRef, ...restProps, children: children }) }));
}), getBackdropTestIds);
//# sourceMappingURL=Backdrop.js.map