import { jsx as _jsx } from "react/jsx-runtime";
import { memo, useCallback, useEffect, useMemo } from 'react';
import markdocLib from '@markdoc/markdoc';
import { LayoutVariant } from '@redocly/config';
import { createStore, Provider } from 'jotai';
import { Heading } from '@redocly/theme/markdoc/components/Heading/Heading';
import { normalizeOptions, OpenAPIParser } from '../../services/index.js';
import { getMarkdownHeaderId } from './utils.js';
import { normalizeServers } from '../../utils/index.js';
import { SchemaDefinition } from '../SchemaDefinition/index.js';
import { appStore, appStoreOverrideAtom, environmentAtom, layoutAtom, userClaimsAtom, } from '../../jotai/app.js';
import { mapObject } from '../../utils/object.js';
import { mergeInMockServer } from '../../models/operation.js';
import { getDefaultOperationStore, operationStore } from '../../jotai/operation.js';
import { getServerEnvName } from '../../utils/environments.js';
import { globalStoreAtom } from '../../jotai/store.js';
const DEFAULT_OPTIONS = {
    // java.io.ObjectStreamField is something generated from java code which is too deep so our docs build crash because of RAM
    ignoreNamedSchemas: ['java.io.ObjectStreamField'],
    maxDisplayedEnumValues: 10,
    markdocOptions: {
        tags: {
            schemaDefinition: {
                render: 'SchemaDefinition',
                attributes: {
                    schemaRef: {
                        type: String,
                    },
                    exampleRef: {
                        type: String,
                    },
                    showReadOnly: {
                        type: Boolean,
                    },
                    showWriteOnly: {
                        type: Boolean,
                    },
                    htmlWrap: {
                        type: String,
                        default: false,
                    },
                },
            },
        },
        nodes: {
            heading: {
                children: ['inline'],
                attributes: {
                    id: { type: String },
                    level: { type: Number, required: true, default: 1 },
                },
                transform(node, config) {
                    const attributes = node.transformAttributes(config);
                    const children = node.transformChildren(config);
                    const id = typeof attributes.id === 'string' ? attributes.id : getMarkdownHeaderId(children);
                    return new markdocLib.Tag('Heading', {
                        ...attributes,
                        id,
                        level: node.attributes.level,
                    }, children);
                },
            },
        },
        components: {
            SchemaDefinition: SchemaDefinition,
            Heading,
        },
    },
};
export const StoreProvider = memo(({ children, options: rawOptions, definitionUrl, definition, withState, }) => {
    const createGlobalStore = useCallback(() => {
        const options = normalizeOptions(rawOptions, DEFAULT_OPTIONS);
        const parser = new OpenAPIParser(definition, definitionUrl, options);
        return { options, parser };
    }, [definition, definitionUrl, rawOptions]);
    const initializedStore = useMemo(() => {
        const store = createStore();
        const globalStoreValue = createGlobalStore();
        store.set(globalStoreAtom, globalStoreValue);
        // fixme: move into separate function + collect all servers from all operations/paths
        const globalServers = normalizeServers(globalStoreValue.parser.definitionUrl, mergeInMockServer(globalStoreValue.parser.definition?.servers || [], globalStoreValue.options.mockServer));
        const serverEnvs = Object.fromEntries(globalServers.map((server) => [
            getServerEnvName(server),
            {
                server: server.url,
                ...mapObject(server.variables || {}, (variable) => variable.default || ''),
            },
        ]));
        store.sub(appStore, () => undefined); // force mount so init data is read from storage
        store.set(layoutAtom, globalStoreValue.options?.layout || LayoutVariant.THREE_PANEL); // set layout atom to update appStore atom with correct layout value
        store.set(environmentAtom, { environments: serverEnvs });
        store.set(userClaimsAtom, withState?.userClaims || {});
        if (withState) {
            store.set(appStoreOverrideAtom, {
                environment: withState.environment,
                environments: withState.environments,
                activeMimeName: withState.activeMimeName,
                userClaims: withState.userClaims,
            });
        }
        if (withState?.operation) {
            const defaultStore = getDefaultOperationStore(withState.operation.pointer, withState.operation.state.requestValues, withState.operation.state.activeExampleName);
            store.set(operationStore(withState.operation.pointer), defaultStore);
        }
        return store;
    }, [createGlobalStore, withState]);
    useEffect(() => {
        if (!withState?.layout)
            return;
        initializedStore.set(layoutAtom, withState?.layout);
    }, [initializedStore, withState?.layout]);
    return _jsx(Provider, { store: initializedStore, children: children });
});
//# sourceMappingURL=Providers.js.map