import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { lazy, memo, Suspense, useCallback, useRef, useState } from 'react';
import { useAtom, useAtomValue } from 'jotai';
import merge from 'deepmerge';
const ReplayOverlay = lazy(async () => import('@redocly/replay').then((module) => ({ default: module.ReplayOverlay })));
import { Button } from '@redocly/theme/components/Button/Button';
import { useFocusTrap, useModalScrollLock } from '@redocly/theme/core/openapi';
import { RocketIcon } from '@redocly/theme/icons/RocketIcon/RocketIcon';
import { CircleDashIcon } from '@redocly/theme/icons/CircleDashIcon/CircleDashIcon';
import { Portal } from '@redocly/theme/components/Portal/Portal';
import { globalOptionsAtom, globalStoreAtom } from '../../jotai/store.js';
import { allOperationsAtom, replayStateAtom } from '../../jotai/replay.js';
import { allOperations, getDefaultOperationStore } from '../../jotai/operation.js';
import { LOADING_STATE } from '../../constants.js';
import { environmentAtom, userClaimsAtom } from '../../jotai/app.js';
import { convertOperationToReplayValueForRedoc } from './utils.js';
import { useTranslate, useTelemetry } from '../../hooks/index.js';
import { JsonPointer } from '../../utils/index.js';
import { getDefaultCollectorUrl } from '../../utils/telemetry.js';
import { createTryItOpenEvent, createTryItSentEvent } from '../../events/index.js';
function ReplayComponent({ operation, corsProxyUrl, fullOpenApi }) {
    const translate = useTranslate();
    const telemetry = useTelemetry();
    const replayRef = useRef(null);
    const { mockServer, oAuth2RedirectURI, routingBasePath } = useAtomValue(globalOptionsAtom);
    const operations = useAtomValue(allOperationsAtom);
    const { parser, options: { events }, } = useAtomValue(globalStoreAtom);
    const userClaims = useAtomValue(userClaimsAtom);
    const [isOpened, setIsOpened] = useState(false);
    const [replayState, setReplayState] = useAtom(replayStateAtom);
    const [allOperationsData, setAllOperations] = useAtom(allOperations);
    const [[, envName], setEnvironment] = useAtom(environmentAtom);
    useFocusTrap(replayRef);
    useModalScrollLock(isOpened);
    const handleReplayParamChange = useCallback(({ operations, environment, environments }) => {
        const changedOperations = operations.reduce((acc, op) => {
            op.requestValues.body =
                op.requestValues.body instanceof URLSearchParams
                    ? Object.fromEntries(op.requestValues.body.entries())
                    : op.requestValues.body;
            const { path, method } = op.apiPath;
            const pointer = JsonPointer.compile(['paths', path, method]);
            acc[pointer] = merge(getDefaultOperationStore(pointer), op);
            return acc;
        }, {});
        setAllOperations({ ...allOperationsData, ...changedOperations });
        setEnvironment({ environment, environments });
    }, [allOperationsData, setAllOperations, setEnvironment]);
    const handleToggle = () => {
        if (replayState !== LOADING_STATE.LOADING) {
            if (!isOpened) {
                telemetry.send({ type: 'openapi_docs.try_it.opened' });
                if (events?.tryItOpen && operation) {
                    const eventPayload = createTryItOpenEvent({
                        operation: operation,
                    });
                    events.tryItOpen(eventPayload);
                }
            }
            setIsOpened(!isOpened);
        }
        if (replayState === LOADING_STATE.NOT_LOADED) {
            setReplayState(LOADING_STATE.LOADING);
        }
    };
    const handleTryItSent = useCallback((isSuccess) => {
        if (events?.tryItSent && operation) {
            const eventPayload = createTryItSentEvent({ operation, isSuccess });
            events.tryItSent(eventPayload);
        }
    }, [events, operation]);
    const getOperationUrl = useCallback((operationId) => {
        if (!operationId)
            return;
        const operation = operations.find((op) => op.operationId === operationId);
        return routingBasePath + operation?.href;
    }, [operations, routingBasePath]);
    if (!fullOpenApi)
        return null;
    return (_jsxs(_Fragment, { children: [_jsx(Button, { onClick: handleToggle, variant: "primary", iconPosition: "left", icon: replayState === LOADING_STATE.LOADING ? _jsx(CircleDashIcon, {}) : _jsx(RocketIcon, {}), children: replayState === LOADING_STATE.LOADING
                    ? translate('openapi.loading', 'Loading...')
                    : translate('openapi.tryIt', 'Try it') }), isOpened && (_jsx(Suspense, { children: _jsx(Portal, { mountId: "api-content", children: _jsx("div", { ref: replayRef, children: _jsx(ReplayOverlay, { activeOperationId: operation.operationId || operation.pointer, api: fullOpenApi, onRequestChange: handleReplayParamChange, onClose: handleToggle, onLoad: () => setReplayState(LOADING_STATE.LOADED), settings: {
                                corsProxyUrl,
                                mockServer,
                                environment: envName,
                                apiId: parser?.definition.info?.['x-metadata']?.apiId,
                                oAuth2RedirectURI,
                                disableCollectionsTab: true,
                                storageKey: routingBasePath,
                                telemetry: {
                                    tracerName: 'try-it',
                                    collectorUrl: getDefaultCollectorUrl(),
                                },
                                convertOperationToReplayValue: (path, method, openAPI) => convertOperationToReplayValueForRedoc(userClaims)(path, method, openAPI),
                                getOperationUrl,
                            }, ...{ onRequestSent: handleTryItSent } }) }) }) }))] }));
}
export const Replay = memo(ReplayComponent);
//# sourceMappingURL=Replay.js.map