import { useEditor } from "../../../editor/hooks/use-editor.js";
import { useJsonPointerLinkSupport } from "../../../editor/hooks/use-json-pointer-link-support.js";
import { createJsonModel } from "../../../editor/helpers/json/create-json-model.js";
import { createYamlModel } from "../../../editor/helpers/yaml/create-yaml-model.js";
import { useEditorMarkers } from "../../../editor/hooks/use-editor-markers.js";
import EditorDiagnosticsPanel_default from "./components/EditorDiagnosticsPanel.vue.js";
import EditorSavePanel_default from "./components/EditorSavePanel.vue.js";
import { getDiagnosticCounts } from "./helpers/get-diagnostic-counts.js";
import { getOperationContext } from "./helpers/get-operation-context.js";
import { getVisibleDiagnostics } from "./helpers/get-visible-diagnostics.js";
import { parseEditorObject } from "./helpers/parse-editor-object.js";
import { stringifyDocument } from "./helpers/stringify-document.js";
import { useEditorState } from "./hooks/use-editor-state.js";
import { computed, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, onBeforeUnmount, onMounted, openBlock, ref, shallowRef, toDisplayString, unref, watch, withCtx } from "vue";
import { ScalarButton, ScalarHotkey, useLoadingState } from "@scalar/components";
import { ScalarIconArrowsIn, ScalarIconArrowsOut } from "@scalar/icons";
import { isObject } from "@scalar/helpers/object/is-object";
import { debounce } from "@scalar/helpers/general/debounce";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
//#region src/v2/features/collection/components/Editor/Editor.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = { class: "grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-3" };
var _hoisted_2 = { class: "flex min-w-0 items-center gap-1 overflow-x-auto whitespace-nowrap" };
var _hoisted_3 = { class: "text-c-3 ml-2 text-[11px]" };
var _hoisted_4 = { class: "text-c-3 ml-2 text-[11px]" };
var _hoisted_5 = {
	"aria-label": "Editor language",
	class: "bg-b-1 shadow-border flex items-center justify-self-center overflow-hidden rounded-lg p-0.5",
	role: "tablist"
};
var _hoisted_6 = { class: "flex min-w-0 shrink-0 items-center gap-2 justify-self-end" };
var _hoisted_7 = { class: "text-c-3 ml-2 text-[11px]" };
var _hoisted_8 = { class: "text-c-3 ml-2 text-[11px]" };
var _hoisted_9 = { class: "flex min-h-0 w-full min-w-0 flex-1 rounded-lg border" };
var _hoisted_10 = { class: "pointer-events-none absolute top-2 right-2 z-10" };
var _hoisted_11 = { key: 1 };
var MAX_VISIBLE_DIAGNOSTICS = 6;
var EDITOR_PERSIST_DEBOUNCE_KEY = "editor:replace-document";
var Editor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
	__name: "Editor",
	props: {
		documentSlug: {},
		document: {},
		eventBus: {},
		layout: {},
		path: {},
		method: {},
		exampleName: {},
		environment: {},
		securitySchemes: {},
		workspaceStore: {},
		activeWorkspace: {},
		plugins: {},
		customThemes: {},
		currentTheme: {},
		isDarkMode: { type: Boolean },
		fetchRegistryDocument: { type: Function },
		telemetry: { type: Boolean },
		onUpdateTelemetry: { type: Function },
		collectionType: {}
	},
	setup(__props) {
		const monacoEditorRef = ref();
		const editorApi = shallowRef();
		const saveLoader = useLoadingState();
		const { isAutoSaveEnabled, isDirty, editorLanguage, isDiagnosticsPaneExpanded, isEditorMaximized, isYamlMode, editorBottomPadding, editorRootClass, getLanguageToggleClass, toggleEditorMaximized } = useEditorState();
		const jsonModel = createJsonModel();
		const yamlModel = createYamlModel();
		const selectedLanguage = ref("json");
		const currentModel = computed(() => {
			return selectedLanguage.value === "json" ? jsonModel : yamlModel;
		});
		const { markers: diagnostics } = useEditorMarkers(computed(() => editorApi.value?.editor));
		const syncEditorBottomPadding = () => {
			editorApi.value?.editor.updateOptions({ padding: {
				top: 0,
				bottom: editorBottomPadding.value
			} });
		};
		const diagnosticCounts = computed(() => getDiagnosticCounts(diagnostics.value));
		const visibleDiagnostics = computed(() => getVisibleDiagnostics(diagnostics.value, MAX_VISIBLE_DIAGNOSTICS));
		const focusDiagnostic = (marker) => {
			const editor = editorApi.value?.editor;
			if (!editor) return;
			editor.setSelection({
				startLineNumber: marker.startLineNumber,
				startColumn: marker.startColumn,
				endLineNumber: marker.endLineNumber,
				endColumn: marker.endColumn
			});
			editor.revealPositionInCenter({
				lineNumber: marker.startLineNumber,
				column: marker.startColumn
			});
		};
		const getEditorValue = () => currentModel.value.model.getValue();
		/** Value from the editor for a specific language (use when switching to avoid reading the wrong model). */
		const getEditorValueForLanguage = (language) => (language === "json" ? jsonModel : yamlModel).model.getValue();
		const getDocumentValue = async (language) => {
			return stringifyDocument(await __props.workspaceStore.getEditableDocument(__props.documentSlug), language ?? selectedLanguage.value);
		};
		const debouncedPersist = debounce({ delay: 1500 });
		const applyProgrammaticEditorValue = (value) => {
			debouncedPersist.cleanup();
			editorApi.value?.setValue(value, true);
		};
		const loadDocumentIntoEditor = async () => {
			applyProgrammaticEditorValue(await getDocumentValue());
			isDirty.value = false;
			await focusOperation();
		};
		const formatDocument = async () => {
			await editorApi.value?.formatDocument();
		};
		const focusOperation = async () => {
			const operationContext = getOperationContext(__props.path, __props.method);
			if (!operationContext) return;
			await editorApi.value?.focusPath([
				"paths",
				operationContext.path,
				operationContext.method
			]);
		};
		const persistEditorToWorkspace = async (value) => {
			const parsed = parseEditorObject(value, editorLanguage.value);
			if (!parsed) {
				const firstError = diagnostics.value.find((m) => m.severity === monaco.MarkerSeverity.Error);
				if (firstError) focusDiagnostic(firstError);
				await saveLoader.invalidate();
				return;
			}
			saveLoader.start();
			await __props.workspaceStore.replaceDocument(__props.documentSlug, parsed);
			isDirty.value = false;
			await saveLoader.validate({ duration: 900 });
		};
		const saveNow = async () => {
			const value = getEditorValue();
			if (!value) return;
			await persistEditorToWorkspace(value);
		};
		const handleEditorChange = (value) => {
			isDirty.value = true;
			if (!isAutoSaveEnabled.value) return;
			debouncedPersist.execute(EDITOR_PERSIST_DEBOUNCE_KEY, () => persistEditorToWorkspace(value));
		};
		const focusOperationServers = async () => {
			const operationContext = getOperationContext(__props.path, __props.method);
			if (!operationContext) return;
			const value = getEditorValue();
			if (!value) return;
			const parsed = parseEditorObject(value, editorLanguage.value);
			if (!parsed || !isObject(parsed.paths)) return;
			const operationPathItem = parsed.paths[operationContext.path];
			if (!isObject(operationPathItem)) return;
			const operation = operationPathItem[operationContext.method];
			if (!isObject(operation)) return;
			operation.servers ??= [];
			editorApi.value?.setValue(stringifyDocument(parsed, editorLanguage.value));
			await editorApi.value?.focusPath([
				"paths",
				operationContext.path,
				operationContext.method,
				"servers"
			]);
		};
		useJsonPointerLinkSupport(editorApi, currentModel);
		onMounted(() => {
			editorApi.value = useEditor({
				element: monacoEditorRef.value ?? document.createElement("div"),
				onChange: handleEditorChange,
				model: currentModel,
				actions: [
					{
						id: "scalar.editor.focusOperation",
						label: "Focus Operation",
						keybindings: [monaco.KeyMod.Alt | monaco.KeyCode.KeyO],
						run: async () => {
							await focusOperation();
						}
					},
					{
						id: "scalar.editor.focusOperationServers",
						label: "Focus Operation Servers",
						keybindings: [monaco.KeyMod.Alt | monaco.KeyCode.KeyS],
						run: async () => {
							await focusOperationServers();
						}
					},
					{
						id: "scalar.editor.formatDocument",
						label: "Format Document",
						keybindings: [monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KeyF],
						run: async () => {
							await formatDocument();
						}
					}
				]
			});
			syncEditorBottomPadding();
			loadDocumentIntoEditor();
		});
		onBeforeUnmount(() => {
			debouncedPersist.cleanup();
			if (isDirty.value && isAutoSaveEnabled.value) saveNow();
			editorApi.value?.dispose?.();
			jsonModel.model.dispose();
			yamlModel.model.dispose();
		});
		watch(() => __props.documentSlug, loadDocumentIntoEditor);
		watch(() => [__props.path, __props.method], async () => {
			await focusOperation();
		});
		watch(isDiagnosticsPaneExpanded, () => {
			syncEditorBottomPadding();
		});
		watch(editorLanguage, async (nextLanguage, previousLanguage) => {
			const wasDirty = isDirty.value;
			const value = getEditorValueForLanguage(previousLanguage ?? "json");
			if (!value) {
				selectedLanguage.value = nextLanguage;
				await nextTick();
				await focusOperation();
				return;
			}
			const parsed = parseEditorObject(value, previousLanguage ?? "json");
			selectedLanguage.value = nextLanguage;
			await nextTick();
			if (parsed) {
				applyProgrammaticEditorValue(stringifyDocument(parsed, nextLanguage));
				isDirty.value = wasDirty;
			}
			await focusOperation();
		});
		watch(isAutoSaveEnabled, (isEnabled) => {
			if (!isEnabled) {
				debouncedPersist.cleanup();
				return;
			}
			if (isDirty.value) {
				const value = getEditorValue();
				if (!value) return;
				debouncedPersist.execute(EDITOR_PERSIST_DEBOUNCE_KEY, () => persistEditorToWorkspace(value));
			}
		}, { flush: "post" });
		return (_ctx, _cache) => {
			return __props.collectionType === "operation" && unref(getOperationContext)(__props.path, __props.method) !== null ? (openBlock(), createElementBlock("div", {
				key: 0,
				class: normalizeClass(["flex w-full min-w-0 flex-1 flex-col gap-2", unref(editorRootClass)])
			}, [createElementVNode("div", _hoisted_1, [
				createElementVNode("div", _hoisted_2, [
					_cache[6] || (_cache[6] = createElementVNode("span", { class: "text-c-2 text-xs font-medium whitespace-nowrap" }, " Shortcuts ", -1)),
					createVNode(unref(ScalarButton), {
						class: "whitespace-nowrap",
						size: "xs",
						variant: "ghost",
						onClick: focusOperation
					}, {
						default: withCtx(() => [_cache[4] || (_cache[4] = createElementVNode("span", null, "Operation", -1)), createElementVNode("span", _hoisted_3, [createVNode(unref(ScalarHotkey), {
							hotkey: "O",
							modifier: ["Alt"]
						})])]),
						_: 1
					}),
					createVNode(unref(ScalarButton), {
						class: "whitespace-nowrap",
						size: "xs",
						variant: "ghost",
						onClick: focusOperationServers
					}, {
						default: withCtx(() => [_cache[5] || (_cache[5] = createElementVNode("span", null, "Servers", -1)), createElementVNode("span", _hoisted_4, [createVNode(unref(ScalarHotkey), {
							hotkey: "S",
							modifier: ["Alt"]
						})])]),
						_: 1
					})
				]),
				createElementVNode("div", _hoisted_5, [createVNode(unref(ScalarButton), {
					"aria-selected": !unref(isYamlMode),
					class: normalizeClass(unref(getLanguageToggleClass)(!unref(isYamlMode))),
					role: "tab",
					size: "xs",
					type: "button",
					variant: "ghost",
					onClick: _cache[0] || (_cache[0] = ($event) => editorLanguage.value = "json")
				}, {
					default: withCtx(() => [..._cache[7] || (_cache[7] = [createTextVNode(" JSON ", -1)])]),
					_: 1
				}, 8, ["aria-selected", "class"]), createVNode(unref(ScalarButton), {
					"aria-selected": unref(isYamlMode),
					class: normalizeClass(unref(getLanguageToggleClass)(unref(isYamlMode))),
					role: "tab",
					size: "xs",
					type: "button",
					variant: "ghost",
					onClick: _cache[1] || (_cache[1] = ($event) => editorLanguage.value = "yaml")
				}, {
					default: withCtx(() => [..._cache[8] || (_cache[8] = [createTextVNode(" YAML ", -1)])]),
					_: 1
				}, 8, ["aria-selected", "class"])]),
				createElementVNode("div", _hoisted_6, [createVNode(unref(ScalarButton), {
					size: "xs",
					variant: "ghost",
					onClick: formatDocument
				}, {
					default: withCtx(() => [createElementVNode("span", null, "Format " + toDisplayString(unref(isYamlMode) ? "YAML" : "JSON"), 1), createElementVNode("span", _hoisted_7, [createVNode(unref(ScalarHotkey), {
						hotkey: "F",
						modifier: ["Alt", "Shift"]
					})])]),
					_: 1
				}), createVNode(unref(ScalarButton), {
					"aria-label": unref(isEditorMaximized) ? "Restore editor size" : "Maximize editor",
					size: "xs",
					variant: "ghost",
					onClick: unref(toggleEditorMaximized)
				}, {
					default: withCtx(() => [createElementVNode("span", null, toDisplayString(unref(isEditorMaximized) ? "Restore" : "Maximize"), 1), createElementVNode("span", _hoisted_8, [unref(isEditorMaximized) ? (openBlock(), createBlock(unref(ScalarIconArrowsIn), {
						key: 0,
						class: "size-3.5"
					})) : (openBlock(), createBlock(unref(ScalarIconArrowsOut), {
						key: 1,
						class: "size-3.5"
					}))])]),
					_: 1
				}, 8, ["aria-label", "onClick"])])
			]), createElementVNode("div", _hoisted_9, [createElementVNode("div", { class: normalizeClass(["relative w-full min-w-0 flex-1", unref(isEditorMaximized) ? "h-full min-h-0" : "h-[500px]"]) }, [
				createElementVNode("div", _hoisted_10, [createVNode(EditorSavePanel_default, {
					isAutoSaveEnabled: unref(isAutoSaveEnabled),
					isDirty: unref(isDirty),
					saveLoader: unref(saveLoader),
					onSaveNow: saveNow,
					"onUpdate:isAutoSaveEnabled": _cache[2] || (_cache[2] = ($event) => isAutoSaveEnabled.value = $event)
				}, null, 8, [
					"isAutoSaveEnabled",
					"isDirty",
					"saveLoader"
				])]),
				createVNode(EditorDiagnosticsPanel_default, {
					diagnosticCounts: diagnosticCounts.value,
					expanded: unref(isDiagnosticsPaneExpanded),
					visibleDiagnostics: visibleDiagnostics.value,
					onFocusDiagnostic: focusDiagnostic,
					onToggle: _cache[3] || (_cache[3] = ($event) => isDiagnosticsPaneExpanded.value = !unref(isDiagnosticsPaneExpanded))
				}, null, 8, [
					"diagnosticCounts",
					"expanded",
					"visibleDiagnostics"
				]),
				createElementVNode("div", {
					ref_key: "monacoEditorRef",
					ref: monacoEditorRef,
					class: "h-full w-full min-w-0 flex-1"
				}, null, 512)
			], 2)])], 2)) : (openBlock(), createElementBlock("div", _hoisted_11, "No operation context found"));
		};
	}
});
//#endregion
export { Editor_vue_vue_type_script_setup_true_lang_default as default };

//# sourceMappingURL=Editor.vue.script.js.map