"use strict";
'use client';
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.LinkWithPreview = LinkWithPreview;
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native");
const hooks_1 = require("../hooks");
const BaseExpoRouterLink_1 = require("./BaseExpoRouterLink");
const InternalLinkPreviewContext_1 = require("./InternalLinkPreviewContext");
const NativeMenuContext_1 = require("./NativeMenuContext");
const elements_1 = require("./elements");
const href_1 = require("./href");
const LinkPreviewContext_1 = require("./preview/LinkPreviewContext");
const native_1 = require("./preview/native");
const useNextScreenId_1 = require("./preview/useNextScreenId");
const children_1 = require("../utils/children");
const url_1 = require("../utils/url");
const isPad = react_native_1.Platform.OS === 'ios' && react_native_1.Platform.isPad;
function LinkWithPreview({ children, ...rest }) {
    const router = (0, hooks_1.useRouter)();
    const { setOpenPreviewKey } = (0, LinkPreviewContext_1.useLinkPreviewContext)();
    const [isCurrentPreviewOpen, setIsCurrenPreviewOpen] = (0, react_1.useState)(false);
    const hrefWithoutQuery = (0, href_1.resolveHref)(rest.hrefForPreviewNavigation).split('?')[0];
    const prevHrefWithoutQuery = (0, react_1.useRef)(hrefWithoutQuery);
    (0, react_1.useEffect)(() => {
        if (isCurrentPreviewOpen) {
            if (prevHrefWithoutQuery.current !== hrefWithoutQuery) {
                throw new Error('Link does not support changing the href prop after the preview has been opened. Please ensure that the href prop is stable and does not change between renders.');
            }
        }
        else {
            prevHrefWithoutQuery.current = hrefWithoutQuery;
        }
    }, [hrefWithoutQuery]);
    const [{ nextScreenId, tabPath }, prefetch] = (0, useNextScreenId_1.useNextScreenId)();
    (0, react_1.useEffect)(() => {
        if (rest.replace) {
            if (process.env.NODE_ENV !== 'production') {
                throw new Error('Using replace links with preview is not supported');
            }
            else {
                console.warn('Using replace links with preview is not supported');
            }
        }
    }, [rest.href, rest.replace]);
    const triggerElement = react_1.default.useMemo(() => (0, children_1.getFirstChildOfType)(children, elements_1.LinkTrigger), [children]);
    const menuElement = react_1.default.useMemo(() => (0, children_1.getFirstChildOfType)(children, elements_1.LinkMenu), [children]);
    const previewElement = react_1.default.useMemo(() => (0, children_1.getFirstChildOfType)(children, elements_1.LinkPreview), [children]);
    if ((previewElement || menuElement) && !triggerElement) {
        if (process.env.NODE_ENV !== 'production') {
            throw new Error('When you use Link.Preview, you must use Link.Trigger to specify the trigger element.');
        }
        else {
            console.warn('When you use Link.Preview, you must use Link.Trigger to specify the trigger element.');
        }
    }
    const trigger = react_1.default.useMemo(() => triggerElement ?? <elements_1.LinkTrigger>{children}</elements_1.LinkTrigger>, [triggerElement, children]);
    const preview = react_1.default.useMemo(() => ((0, url_1.shouldLinkExternally)(String(rest.href)) || !previewElement ? null : previewElement), [previewElement, rest.href]);
    const isPreviewTapped = (0, react_1.useRef)(false);
    const blockPressRef = (0, react_1.useRef)(false);
    const tabPathValue = (0, react_1.useMemo)(() => ({
        path: tabPath,
    }), [tabPath]);
    const hasPreview = !!previewElement;
    if (rest.replace) {
        return <BaseExpoRouterLink_1.BaseExpoRouterLink children={children} {...rest}/>;
    }
    return (<native_1.NativeLinkPreview nextScreenId={isPad ? undefined : nextScreenId} tabPath={isPad ? undefined : tabPathValue} onWillPreviewOpen={() => {
            if (hasPreview) {
                blockPressRef.current = true;
                isPreviewTapped.current = false;
                prefetch(rest.href);
                setIsCurrenPreviewOpen(true);
            }
        }} onPreviewWillClose={() => {
            if (hasPreview) {
                setIsCurrenPreviewOpen(false);
                // When preview was not tapped, then we need to enable the screen stack animation
                // Otherwise this will happen in StackNavigator, when new screen is opened
                if (!isPreviewTapped.current || isPad) {
                    setOpenPreviewKey(undefined);
                }
            }
        }} onPreviewDidClose={() => {
            blockPressRef.current = false;
            if (hasPreview && isPreviewTapped.current && isPad) {
                router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });
            }
        }} onPreviewTapped={() => {
            isPreviewTapped.current = true;
            if (!isPad) {
                router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });
            }
        }} style={{ display: 'contents' }} disableForceFlatten>
      <NativeMenuContext_1.NativeMenuContext value>
        <InternalLinkPreviewContext_1.InternalLinkPreviewContext value={{
            isVisible: isCurrentPreviewOpen,
            href: rest.hrefForPreviewNavigation,
            blockPressRef,
        }}>
          <BaseExpoRouterLink_1.BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref}/>
          {preview}
          {menuElement}
        </InternalLinkPreviewContext_1.InternalLinkPreviewContext>
      </NativeMenuContext_1.NativeMenuContext>
    </native_1.NativeLinkPreview>);
}
//# sourceMappingURL=LinkWithPreview.js.map