import { useWorkspace } from "../../../store/store.js";
import { useFileDialog } from "../../../hooks/useFileDialog.js";
import CodeInput_default from "../../../components/CodeInput/CodeInput.vue.js";
import DataTable_default from "../../../components/DataTable/DataTable.vue.js";
import DataTableHeader_default from "../../../components/DataTable/DataTableHeader.vue.js";
import DataTableRow_default from "../../../components/DataTable/DataTableRow.vue.js";
import ViewLayoutCollapse_default from "../../../components/ViewLayout/ViewLayoutCollapse.vue.js";
import RequestTable_default from "./RequestTable.vue.js";
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, openBlock, ref, toDisplayString, unref, watch, withCtx } from "vue";
import { ScalarButton, ScalarIcon, ScalarListbox } from "@scalar/components";
import { canMethodHaveBody } from "@scalar/oas-utils/helpers";
import { requestExampleParametersSchema } from "@scalar/oas-utils/entities/spec";
//#region src/views/Request/RequestSection/RequestBody.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = {
	key: 0,
	class: "text-c-3 flex min-h-10 w-full items-center justify-center border-t p-2 text-sm"
};
var _hoisted_2 = {
	key: 1,
	class: "flex items-center justify-center overflow-hidden border-t p-1.5"
};
var _hoisted_3 = { class: "text-c-2 w-full max-w-full overflow-hidden rounded border px-1.5 py-1 text-xs whitespace-nowrap" };
/** Convert content types to options for the dropdown */
var RequestBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
	__name: "RequestBody",
	props: {
		example: {},
		operation: {},
		environment: {},
		envVariables: {},
		workspace: {},
		title: {}
	},
	setup(__props) {
		const { requestExampleMutators } = useWorkspace();
		/** use-codemirror package to be updated accordingly */
		const contentTypeToLanguageMap = {
			json: "json",
			xml: "xml",
			yaml: "yaml",
			edn: "edn",
			other: "html"
		};
		const contentTypeOptions = Object.entries({
			multipartForm: "Multipart Form",
			formUrlEncoded: "Form URL Encoded",
			binaryFile: "Binary File",
			json: "JSON",
			xml: "XML",
			yaml: "YAML",
			edn: "EDN",
			other: "Other",
			none: "None"
		}).map(([id, label]) => ({
			id,
			label
		}));
		/** Match the activeBody to the contentTypeOptions */
		const activeExampleContentType = computed(() => {
			const { activeBody, formData, raw } = __props.example.body;
			if (activeBody === "formData") return formData?.encoding === "urlencoded" ? "formUrlEncoded" : "multipartForm";
			if (activeBody === "binary") return "binaryFile";
			if (activeBody === "raw" && raw?.encoding) {
				if (raw.encoding === "html" || raw.encoding === "text") return "other";
				return raw.encoding;
			}
			return Object.keys(__props.operation.requestBody?.content || {})[0] || "none";
		});
		/** Selected ref from options above */
		const selectedContentType = computed({
			get: () => contentTypeOptions.find((opt) => opt.id === activeExampleContentType.value) ?? contentTypeOptions[contentTypeOptions.length - 1] ?? contentTypeOptions[0],
			set: (opt) => {
				if (opt?.id) updateActiveBody(opt.id);
			}
		});
		const tableWrapperRef = ref(null);
		const codeInputLanguage = computed(() => {
			return contentTypeToLanguageMap[selectedContentType.value?.id] ?? "plaintext";
		});
		const deleteRow = (rowIdx) => {
			const currentParams = formParams.value;
			if (currentParams.length > rowIdx) {
				const updatedParams = [...currentParams];
				updatedParams.splice(rowIdx, 1);
				requestExampleMutators.edit(__props.example.uid, "body.formData.value", updatedParams);
			}
		};
		/** Update a field in a parameter row */
		const updateRow = (rowIdx, field, value) => {
			const currentParams = formParams.value;
			if (currentParams.length > rowIdx) {
				const updatedParams = [...currentParams];
				updatedParams[rowIdx] = {
					...updatedParams[rowIdx],
					value: updatedParams[rowIdx]?.value || "",
					key: updatedParams[rowIdx]?.key || "",
					enabled: updatedParams[rowIdx]?.enabled ?? false,
					[field]: value || ""
				};
				/** enable row key or value is filled */
				if (updatedParams[rowIdx]?.key !== "" || updatedParams[rowIdx]?.value !== "") updatedParams[rowIdx].enabled = true;
				/** check key and value input state */
				if (updatedParams[rowIdx]?.key === "" && updatedParams[rowIdx]?.value === "")
 /** remove if empty */
				updatedParams.splice(rowIdx, 1);
				requestExampleMutators.edit(__props.example.uid, "body.formData.value", updatedParams);
			} else {
				/** if there is no row at the index, add a new one */
				const payload = [requestExampleParametersSchema.parse({ [field]: value })];
				requestExampleMutators.edit(__props.example.uid, "body.formData.value", payload);
				/** focus the new row */
				nextTick(() => {
					if (!tableWrapperRef.value) return;
					tableWrapperRef.value.querySelectorAll("input")[field === "key" ? 0 : 1]?.focus();
				});
			}
			if (rowIdx === currentParams.length - 1) addRow();
		};
		const formParams = computed(() => __props.example.body.formData?.value ?? []);
		/** ensure one empty row by default */
		const defaultRow = () => {
			const lastParam = formParams.value[formParams.value.length - 1];
			if (!lastParam || lastParam.key !== "" || lastParam.value !== "") addRow();
		};
		/** Add a new row to a given parameter list */
		const addRow = () => {
			/** Create a new parameter instance with 'enabled' set to false */
			const newParam = requestExampleParametersSchema.parse({ enabled: false });
			const newParams = [...formParams.value, newParam];
			if (__props.example.body.formData) requestExampleMutators.edit(__props.example.uid, "body.formData.value", newParams);
			else requestExampleMutators.edit(__props.example.uid, "body.formData", {
				value: newParams,
				encoding: "form-data"
			});
		};
		/** Enable and disables the row */
		const toggleRow = (rowIdx, enabled) => {
			const currentParams = formParams.value;
			if (currentParams.length > rowIdx) {
				const updatedParams = [...currentParams];
				if (updatedParams[rowIdx]) updatedParams[rowIdx].enabled = enabled;
				requestExampleMutators.edit(__props.example.uid, "body.formData.value", updatedParams);
			}
		};
		const updateRequestBody = (value) => requestExampleMutators.edit(__props.example.uid, "body.raw.value", value);
		/** Take the select option and return bodyType with encoding and header */
		const getBodyType = (type) => {
			if (type === "multipartForm") return {
				activeBody: "formData",
				encoding: "form-data",
				header: "multipart/form-data"
			};
			if (type === "formUrlEncoded") return {
				activeBody: "formData",
				encoding: "urlencoded",
				header: "application/x-www-form-urlencoded"
			};
			if (type === "binaryFile") return {
				activeBody: "binary",
				encoding: void 0,
				header: "application/octet-stream"
			};
			if (type === "json") return {
				activeBody: "raw",
				encoding: "json",
				header: Object.keys(__props.operation.requestBody?.content ?? {}).find((t) => t.includes("json") || t.endsWith("+json")) || "application/json"
			};
			if (type === "xml") return {
				activeBody: "raw",
				encoding: "xml",
				header: "application/xml"
			};
			if (type === "yaml") return {
				activeBody: "raw",
				encoding: "yaml",
				header: "application/yaml"
			};
			if (type === "edn") return {
				activeBody: "raw",
				encoding: "edn",
				header: "application/edn"
			};
			if (type === "other") {
				const textContentType = Object.keys(__props.operation.requestBody?.content ?? {}).find((t) => t.startsWith("text/"));
				return {
					activeBody: "raw",
					encoding: textContentType ? "text" : "html",
					header: textContentType ?? "application/html"
				};
			}
			return {
				activeBody: "raw",
				encoding: void 0,
				header: void 0
			};
		};
		/** Set active body AND encoding */
		const updateActiveBody = (type) => {
			const { activeBody, encoding, header } = getBodyType(type);
			requestExampleMutators.edit(__props.example.uid, "body.activeBody", activeBody);
			if (encoding && activeBody === "raw") requestExampleMutators.edit(__props.example.uid, "body.raw", {
				encoding,
				value: __props.example.body.raw?.value ?? ""
			});
			else if (encoding && activeBody === "formData") requestExampleMutators.edit(__props.example.uid, "body.formData", {
				encoding,
				value: __props.example.body.formData?.value ?? []
			});
			else if (!encoding && activeBody !== "binary") {
				const { raw: deleteMe, ...body } = __props.example.body;
				requestExampleMutators.edit(__props.example.uid, "body", body);
			}
			const headers = [...__props.example.parameters.headers];
			const contentTypeIdx = headers.findIndex((h) => h.key.toLowerCase() === "content-type");
			if (contentTypeIdx >= 0) {
				if (header && headers[contentTypeIdx]) headers[contentTypeIdx].value = header;
				else if (headers[contentTypeIdx] && (activeBody !== "raw" || type === "none")) headers.splice(contentTypeIdx, 1);
			} else if (header) {
				const lastHeader = headers[headers.length - 1];
				if (lastHeader && lastHeader.key === "" && lastHeader.value === "") headers.splice(headers.length - 1, 0, {
					key: "Content-Type",
					value: header,
					enabled: true
				});
				else headers.push({
					key: "Content-Type",
					value: header,
					enabled: true
				});
			}
			requestExampleMutators.edit(__props.example.uid, "parameters.headers", headers);
		};
		const handleFileUploadFormData = (rowIdx) => {
			const { open } = useFileDialog({
				onChange: (files) => {
					const file = files?.[0];
					if (file) {
						const updatedParams = [...formParams.value];
						updatedParams[rowIdx] = {
							...updatedParams[rowIdx],
							file,
							value: updatedParams[rowIdx]?.value || file.name,
							key: updatedParams[rowIdx]?.key || file.name,
							enabled: true
						};
						requestExampleMutators.edit(__props.example.uid, "body.formData.value", updatedParams);
						defaultRow();
					}
				},
				multiple: false,
				accept: "*/*"
			});
			open();
		};
		const removeBinaryFile = () => requestExampleMutators.edit(__props.example.uid, "body.binary", void 0);
		function handleRemoveFileFormData(rowIdx) {
			const currentParams = formParams.value;
			const updatedParams = [...currentParams];
			const param = currentParams[rowIdx];
			const file = param?.file;
			if (currentParams.length > 1 && (!param?.key && !param?.value || file && param?.key === file.name && param?.value === file.name)) updatedParams.splice(rowIdx, 1);
			else if (updatedParams[rowIdx]) updatedParams[rowIdx].file = void 0;
			requestExampleMutators.edit(__props.example.uid, "body.formData.value", updatedParams);
		}
		function handleFileUpload() {
			const { open } = useFileDialog({
				onChange: (files) => {
					const file = files?.[0];
					if (file) requestExampleMutators.edit(__props.example.uid, "body.binary", file);
				},
				multiple: false,
				accept: "*/*"
			});
			open();
		}
		watch(selectedContentType, (val) => {
			if (["multipartForm", "formUrlEncoded"].includes(val?.id || "")) defaultRow();
		}, { immediate: true });
		watch(() => __props.example.uid, () => {
			__props.operation.method && canMethodHaveBody(__props.operation.method) && updateActiveBody(activeExampleContentType.value);
			if (["multipartForm", "formUrlEncoded"].includes(activeExampleContentType.value)) defaultRow();
		}, { immediate: true });
		const exampleOptions = computed(() => {
			const contentType = selectedContentType.value?.id;
			const { header } = getBodyType(contentType);
			const content = __props.operation.requestBody?.content || {};
			const examples = header ? content[header]?.examples || {} : {};
			return Object.entries(examples).map(([key, value]) => ({
				id: key,
				label: key,
				value
			}));
		});
		const selectedExample = computed({
			get: () => {
				const rawValue = __props.example.body.raw?.value ?? "{}";
				try {
					const parsedValue = JSON.parse(rawValue);
					return exampleOptions.value.find((e) => {
						const exampleValue = e.value;
						return JSON.stringify(exampleValue.value) === JSON.stringify(parsedValue);
					}) ?? exampleOptions.value[0];
				} catch {
					return exampleOptions.value[0];
				}
			},
			set: (opt) => {
				if (opt?.id) {
					const exampleOption = exampleOptions.value.find((e) => e.id === opt.id);
					if (exampleOption) {
						const exampleValue = exampleOption.value;
						updateRequestBody(JSON.stringify(exampleValue.value, null, 2));
					}
				}
			}
		});
		return (_ctx, _cache) => {
			return openBlock(), createBlock(ViewLayoutCollapse_default, null, {
				title: withCtx(() => [createTextVNode(toDisplayString(__props.title), 1)]),
				default: withCtx(() => [createVNode(DataTable_default, {
					columns: [""],
					presentational: ""
				}, {
					default: withCtx(() => [
						createVNode(DataTableRow_default, null, {
							default: withCtx(() => [createVNode(DataTableHeader_default, { class: "relative col-span-full flex h-8 cursor-pointer items-center justify-between !p-0" }, {
								default: withCtx(() => [createVNode(unref(ScalarListbox), {
									modelValue: selectedContentType.value,
									"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedContentType.value = $event),
									options: unref(contentTypeOptions),
									teleport: ""
								}, {
									default: withCtx(() => [createVNode(unref(ScalarButton), {
										class: "text-c-2 hover:text-c-1 flex h-full w-fit gap-1.5 px-3 font-normal",
										variant: "ghost"
									}, {
										default: withCtx(() => [createElementVNode("span", null, toDisplayString(selectedContentType.value?.label), 1), createVNode(unref(ScalarIcon), {
											icon: "ChevronDown",
											size: "md"
										})]),
										_: 1
									})]),
									_: 1
								}, 8, ["modelValue", "options"]), exampleOptions.value.length > 0 ? (openBlock(), createBlock(unref(ScalarListbox), {
									key: 0,
									modelValue: selectedExample.value,
									"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => selectedExample.value = $event),
									options: exampleOptions.value,
									side: "left",
									teleport: ""
								}, {
									default: withCtx(() => [createVNode(unref(ScalarButton), {
										class: "text-c-2 hover:text-c-1 flex h-full w-fit gap-1.5 px-2 font-normal",
										fullWidth: "",
										variant: "ghost"
									}, {
										default: withCtx(() => [createElementVNode("span", null, toDisplayString(selectedExample.value?.label), 1), createVNode(unref(ScalarIcon), {
											icon: "ChevronDown",
											size: "md"
										})]),
										_: 1
									})]),
									_: 1
								}, 8, ["modelValue", "options"])) : createCommentVNode("", true)]),
								_: 1
							})]),
							_: 1
						}),
						createVNode(DataTableRow_default, null, {
							default: withCtx(() => [selectedContentType.value?.id === "none" ? (openBlock(), createElementBlock("div", _hoisted_1, [..._cache[2] || (_cache[2] = [createElementVNode("span", null, "No Body", -1)])])) : selectedContentType.value?.id === "binaryFile" ? (openBlock(), createElementBlock("div", _hoisted_2, [__props.example.body.binary ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createElementVNode("span", _hoisted_3, toDisplayString(__props.example.body.binary.name), 1), createVNode(unref(ScalarButton), {
								class: "bg-b-2 hover:bg-b-3 text-c-2 ml-1 border-0 shadow-none",
								size: "sm",
								variant: "outlined",
								onClick: removeBinaryFile
							}, {
								default: withCtx(() => [..._cache[3] || (_cache[3] = [createTextVNode(" Delete ", -1)])]),
								_: 1
							})], 64)) : (openBlock(), createBlock(unref(ScalarButton), {
								key: 1,
								class: "bg-b-2 hover:bg-b-3 text-c-2 border-0 shadow-none",
								size: "sm",
								variant: "outlined",
								onClick: handleFileUpload
							}, {
								default: withCtx(() => [_cache[4] || (_cache[4] = createElementVNode("span", null, "Upload File", -1)), createVNode(unref(ScalarIcon), {
									class: "ml-1",
									icon: "Upload",
									size: "xs",
									thickness: "2.5"
								})]),
								_: 1
							}))])) : selectedContentType.value?.id == "multipartForm" ? (openBlock(), createBlock(RequestTable_default, {
								key: 2,
								ref_key: "tableWrapperRef",
								ref: tableWrapperRef,
								class: "!m-0 rounded-t-none border-t-0 border-r-0 border-b-0 border-l-0 shadow-none",
								columns: [
									"32px",
									"",
									"",
									"104px"
								],
								envVariables: __props.envVariables,
								environment: __props.environment,
								items: formParams.value,
								showUploadButton: "",
								workspace: __props.workspace,
								onDeleteRow: deleteRow,
								onRemoveFile: handleRemoveFileFormData,
								onToggleRow: toggleRow,
								onUpdateRow: updateRow,
								onUploadFile: handleFileUploadFormData
							}, null, 8, [
								"envVariables",
								"environment",
								"items",
								"workspace"
							])) : selectedContentType.value?.id == "formUrlEncoded" ? (openBlock(), createBlock(RequestTable_default, {
								key: 3,
								ref_key: "tableWrapperRef",
								ref: tableWrapperRef,
								class: "!m-0 rounded-t-none border-t-0 border-r-0 border-b-0 border-l-0 shadow-none",
								columns: [
									"32px",
									"",
									"",
									"104px"
								],
								envVariables: __props.envVariables,
								environment: __props.environment,
								items: formParams.value,
								showUploadButton: "",
								workspace: __props.workspace,
								onDeleteRow: deleteRow,
								onRemoveFile: handleRemoveFileFormData,
								onToggleRow: toggleRow,
								onUpdateRow: updateRow,
								onUploadFile: handleFileUploadFormData
							}, null, 8, [
								"envVariables",
								"environment",
								"items",
								"workspace"
							])) : (openBlock(), createBlock(CodeInput_default, {
								key: 4,
								class: "border-t px-3",
								content: "",
								envVariables: __props.envVariables,
								environment: __props.environment,
								language: codeInputLanguage.value,
								lineNumbers: "",
								lint: "",
								modelValue: __props.example.body?.raw?.value ?? "",
								workspace: __props.workspace,
								"onUpdate:modelValue": updateRequestBody
							}, null, 8, [
								"envVariables",
								"environment",
								"language",
								"modelValue",
								"workspace"
							]))]),
							_: 1
						}),
						createVNode(DataTableRow_default)
					]),
					_: 1
				})]),
				_: 1
			});
		};
	}
});
//#endregion
export { RequestBody_vue_vue_type_script_setup_true_lang_default as default };

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