import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { forwardRef, useState, useRef, useContext, useEffect } from 'react';
import styled, { css } from 'styled-components';
import Button from '../Button';
import Popover from '../Popover';
import BareButton from '../Button/BareButton';
import { defaultThemeProp } from '../../theme';
import { useBreakpoint, useConsolidatedRef, useI18n, useUID, useModalContext, useOS, useTestIds } from '../../hooks';
import { documentIsAvailable, tryCatch, withTestIds } from '../../utils';
import { calculateFontSize, readableColor } from '../../styles';
import AppShellContext from '../AppShell/AppShellContext';
import { Keyboard } from '../Badges';
import Text, { StyledText } from '../Text';
import { StyledKeyboard } from '../Badges/Keyboard';
import Flex from '../Flex';
import Icon, { StyledIcon, registerIcon } from '../Icon';
import * as openIcon from '../Icon/icons/open.icon';
import VisuallyHiddenText from '../VisuallyHiddenText';
import { useFullscreenContext } from '../Fullscreen';
import { getLinkTestIds } from './Link.test-ids';
export const StyledLinkPopover = styled.div(({ theme, preview }) => css `
    background-color: ${theme.components.tooltip['background-color']};
    z-index: ${theme.base['z-index'].tooltip};

    ${preview &&
    css `
      padding: ${theme.base.spacing};
    `}
  `);
StyledLinkPopover.defaultProps = defaultThemeProp;
export const StyledLinkPopoverBtn = styled(BareButton)(({ theme }) => {
    const contrastColor = tryCatch(() => readableColor(theme.components.tooltip['background-color']));
    const fontSize = calculateFontSize(theme.base['font-size'], theme.base['font-scale']);
    return css `
    position: relative;
    display: inline-flex;
    align-items: center;
    z-index: 1;
    padding: 0 ${theme.base.spacing};
    min-height: 1.5rem;
    line-height: 1;
    color: ${contrastColor};
    font-size: ${fontSize.xs};
    text-decoration: none;

    /* FIXME: Button selector specificity... */
    & + & {
      margin: 0;
    }

    & + &::before {
      content: '';
      position: absolute;
      inset-inline-start: 0;
      inset-block: 0;
      width: 1px; /* stylelint-disable-line unit-allowed-list */
      background-color: ${contrastColor};
      opacity: ${theme.base.transparency['transparent-3']};
    }

    &:hover,
    &:active {
      text-decoration: underline;
    }

    &:focus {
      box-shadow:
        inset 0 0 0 0.0625rem ${theme.base.palette.light},
        0 0 0.125rem 0.0625rem ${theme.base.palette.interactive};
    }
  `;
});
StyledLinkPopoverBtn.defaultProps = defaultThemeProp;
export const StyledLinkPreviewPopoverBtn = styled(StyledLinkPopoverBtn)(({ theme }) => {
    return css `
    width: 100%;
    padding: unset;

    &:hover,
    &:active {
      text-decoration: none;
      ${StyledText} span {
        text-decoration: underline;
      }
    }

    ${StyledText} {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 100%;
    }

    ${StyledKeyboard} {
      color: ${theme.base.palette.light};
      background-color: ${theme.base.colors.gray.dark};
      border-color: ${theme.base.colors.gray.medium};
      inset-block-start: unset;

      &:first-of-type {
        margin-inline: ${theme.base.spacing};
      }
    }
  `;
});
StyledLinkPreviewPopoverBtn.defaultProps = defaultThemeProp;
export const StyledLink = styled(Button) `
  &:has(> img) {
    display: inline-block;

    ${StyledIcon} {
      vertical-align: top;
    }
  }
`;
StyledLink.defaultProps = defaultThemeProp;
registerIcon(openIcon);
// Blocks usage of "javascript:" scheme.
// @see https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/shared/sanitizeURL.js#L19-L20
const disallowedURI = // eslint-disable-next-line no-control-regex
 /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;
const Link = forwardRef(function Link({ testId, href: hrefProp, variant = 'link', icon = false, previewable: showPreviewOpenInTabPopoverProp = false, onPreview, target: targetProp, children, ...restProps }, ref) {
    const href = disallowedURI.test(hrefProp) ? undefined : hrefProp;
    const { initialized: inModal } = useModalContext();
    const fullscreen = useFullscreenContext();
    const inFullscreen = !!(fullscreen && fullscreen[0]);
    const { previewTriggerRef } = useContext(AppShellContext);
    const uid = useUID();
    const linkRef = useConsolidatedRef(ref);
    const [popover, setPopover] = useState(false);
    const [popoverHideDelay, setPopoverHideDelay] = useState('short');
    const [previewPopover, setPreviewPopover] = useState(false);
    const previewBtnRef = useRef(null);
    const isSmallOrAbove = useBreakpoint('sm');
    const t = useI18n();
    const { macintosh } = useOS();
    const contextMenuOpened = useRef(false);
    const testIds = useTestIds(testId, getLinkTestIds);
    const previewable = showPreviewOpenInTabPopoverProp && !inModal && !inFullscreen;
    let crossOrigin;
    try {
        if (href) {
            const url = new URL(href, document.location.href);
            crossOrigin = documentIsAvailable
                ? /^https?:$/.test(url.protocol) && document.location.origin !== url.origin
                : false;
        }
        else {
            crossOrigin = false;
        }
    }
    catch {
        crossOrigin = false;
    }
    const target = crossOrigin ? '_blank' : targetProp;
    const showPopover = () => {
        if (isSmallOrAbove && !previewPopover) {
            setPopover(true);
        }
    };
    const showPreviewPopover = () => {
        if (isSmallOrAbove && !popover && !contextMenuOpened.current)
            setPreviewPopover(true);
    };
    const hidePopover = () => {
        setPopover(false);
    };
    const hidePreviewPopover = () => {
        setPreviewPopover(false);
    };
    const onBlurLink = () => {
        contextMenuOpened.current = false;
        hidePreviewPopover();
    };
    const onPreviewClick = () => {
        previewTriggerRef.current = linkRef.current;
        if (href !== undefined) {
            onPreview?.({ href });
        }
    };
    const onKeyUp = (e) => {
        if (e.getModifierState('Alt') && e.code === 'KeyP') {
            onPreviewClick();
        }
    };
    useEffect(() => {
        if (popoverHideDelay === 'none' && !popover && !previewPopover) {
            setPopoverHideDelay('short');
        }
    }, [popoverHideDelay, popover, previewPopover]);
    useEffect(() => {
        const onKeyDown = ({ key }) => {
            if (key === 'Escape' && (popover || previewPopover)) {
                setPopoverHideDelay('none');
                setPopover(false);
                setPreviewPopover(false);
            }
        };
        document.addEventListener('keydown', onKeyDown);
        return () => {
            document.removeEventListener('keydown', onKeyDown);
        };
    }, [popover, previewPopover]);
    return (_jsxs(_Fragment, { children: [_jsxs(StyledLink, { "data-testid": testIds.root, href: href, variant: variant, ref: linkRef, target: target, ...restProps, "aria-describedby": previewable ? `${uid}-preview-instructions` : undefined, onMouseEnter: showPreviewOpenInTabPopoverProp
                    ? () => {
                        showPopover();
                    }
                    : undefined, onMouseLeave: hidePopover, onFocus: showPreviewOpenInTabPopoverProp
                    ? () => {
                        showPreviewPopover();
                    }
                    : undefined, onBlur: onBlurLink, onKeyUp: onKeyUp, onContextMenu: () => {
                    contextMenuOpened.current = true;
                    setPopoverHideDelay('none');
                    setPreviewPopover(false);
                    setPopover(false);
                }, children: [children, target === '_blank' && _jsx(VisuallyHiddenText, { children: t('opens_in_a_new_tab') }), !icon && target === '_blank' && _jsx(Icon, { name: 'open' })] }), previewable && (_jsx(Popover, { "data-testid": testIds.previewPopover, show: previewPopover, groupId: 'link_preview', showDelay: 'short', hideDelay: popoverHideDelay, placement: 'bottom', target: linkRef.current, as: StyledLinkPopover, arrow: true, preview: true, portal: true, onHide: hidePreviewPopover, onClick: (e) => {
                    e.stopPropagation();
                }, children: _jsx(StyledLinkPreviewPopoverBtn, { "data-testid": testIds.preview, preview: true, type: 'button', ref: previewBtnRef, onClick: onPreviewClick, tabIndex: '-1', children: _jsxs(Text, { children: [_jsx("span", { children: t('preview') }), _jsxs(Flex, { container: { inline: true, justify: 'end' }, children: [_jsx(Keyboard, { keyName: 'Alt' }), _jsx(Keyboard, { keyName: 'P' })] })] }) }) })), _jsxs(Popover, { "data-testid": testIds.previewPopover, show: popover, groupId: 'link_preview', showDelay: 'short', hideDelay: popoverHideDelay, placement: 'bottom', target: linkRef.current, onMouseEnter: showPopover, onMouseLeave: hidePopover, as: StyledLinkPopover, arrow: true, portal: true, onClick: (e) => {
                    e.stopPropagation();
                }, children: [previewable && (_jsx(StyledLinkPopoverBtn, { "data-testid": testIds.preview, preview: true, type: 'button', ref: previewBtnRef, onClick: onPreviewClick, tabIndex: '-1', children: t('preview') })), _jsx(StyledLinkPopoverBtn, { "data-testid": testIds.newTab, forwardedAs: 'a', href: href, target: '_blank', rel: 'noreferrer', tabIndex: '-1', children: t('link_open_in_tab_text') })] }), previewable && (_jsx("span", { id: `${uid}-preview-instructions`, hidden: true, children: t('preview_link_instruction', [macintosh ? 'option' : 'alt']) }))] }));
});
export default withTestIds(Link, getLinkTestIds);
//# sourceMappingURL=Link.js.map