import { n as __exportAll } from "./chunk-B-1-B7_t.js";
import { n as cn } from "./utils-DXzSsU1e.js";
import { n as Button_default } from "./button-B9CnnuTu.js";
import { o as CardContent_default, r as CardHeader_default, s as Card_default } from "./card-X74FuL7B.js";
import { t as Input_default } from "./input-CwDp-vE8.js";
import { l as SelectContent_default, n as SelectTrigger_default, s as SelectItem_default, t as SelectValue_default, u as Select_default } from "./select-Dwoxq29k.js";
import { t as Textarea_default } from "./textarea-Bi7Nstc4.js";
import { t as FieldFrame_default } from "./field-frame-DhCOWcMP.js";
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, onMounted, openBlock, ref, renderList, toDisplayString, unref, watch, withCtx } from "vue";
import { GitBranch, Loader2, Save } from "@lucide/vue";
//#region src/components/compositions/elements/code/GitCodeEditor.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = { class: "flex flex-wrap items-center gap-2" };
var _hoisted_2 = {
	key: 0,
	class: "flex items-center gap-1.5 rounded-md bg-muted px-2 py-1 text-xs text-muted-foreground",
	"data-testid": "git-code-editor-repository"
};
var _hoisted_3 = {
	class: "min-w-40",
	"data-testid": "git-code-editor-branch-wrapper"
};
var _hoisted_4 = {
	key: 0,
	class: "text-[10px] uppercase tracking-wide text-muted-foreground",
	"data-testid": "git-code-editor-language"
};
var _hoisted_5 = {
	key: 0,
	class: "flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground",
	"data-testid": "git-code-editor-loading"
};
var GitCodeEditor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
	__name: "GitCodeEditor",
	props: {
		repository: {},
		branch: {},
		path: {},
		modelValue: {},
		onLoadBranches: {},
		onLoadFile: {},
		onSaveFile: {},
		language: { default: "plaintext" },
		readonly: { type: Boolean },
		disabled: { type: Boolean },
		required: { type: Boolean },
		label: { default: "Git Code Editor" },
		hideLabel: { type: Boolean },
		name: {},
		id: {},
		helpText: {},
		errors: { default: () => [] },
		classList: {}
	},
	emits: [
		"update:modelValue",
		"update:branch",
		"update:path",
		"update:language"
	],
	setup(__props, { expose: __expose, emit: __emit }) {
		/**
		* Props-driven git code editor composition. Wraps a textarea editor
		* with a branch switcher, file-path input, and a save button. The
		* composition makes no HTTP calls — the consumer supplies Promise-
		* returning callbacks for loading branches, loading a file, and
		* (optionally) saving it.
		*
		*   <GitCodeEditor
		*     repository="gramercy/plugins"
		*     v-model:branch="branch"
		*     v-model:path="path"
		*     v-model="content"
		*     :on-load-branches="loadBranches"
		*     :on-load-file="loadFile"
		*     :on-save-file="saveFile"
		*   />
		*/
		const props = __props;
		const emit = __emit;
		const content = ref(props.modelValue ?? "");
		const branchRef = ref(props.branch ?? "");
		const pathRef = ref(props.path ?? "");
		const languageRef = ref(props.language ?? "plaintext");
		watch(() => props.modelValue, (next) => {
			if (next !== void 0 && next !== content.value) content.value = next;
		});
		watch(() => props.branch, (next) => {
			if (next !== void 0 && next !== branchRef.value) branchRef.value = next;
		});
		watch(() => props.path, (next) => {
			if (next !== void 0 && next !== pathRef.value) pathRef.value = next;
		});
		watch(() => props.language, (next) => {
			if (next !== void 0 && next !== languageRef.value) languageRef.value = next;
		});
		function updateContent(next) {
			const value = next ?? "";
			content.value = value;
			emit("update:modelValue", value);
		}
		function updateBranch(next) {
			branchRef.value = next;
			emit("update:branch", next);
		}
		function updatePath(next) {
			const v = next === void 0 ? "" : String(next);
			pathRef.value = v;
			emit("update:path", v);
		}
		const branches = ref([]);
		const branchesLoading = ref(false);
		const branchesError = ref(null);
		async function loadBranches() {
			if (!props.onLoadBranches) return;
			branchesLoading.value = true;
			branchesError.value = null;
			try {
				const next = await props.onLoadBranches();
				branches.value = Array.isArray(next) ? next : [];
			} catch (err) {
				branchesError.value = err instanceof Error ? err.message : String(err);
				branches.value = [];
			} finally {
				branchesLoading.value = false;
			}
		}
		const fileLoading = ref(false);
		const fileError = ref(null);
		let fileToken = 0;
		async function loadFile() {
			if (!props.onLoadFile) return;
			if (!pathRef.value || !branchRef.value) return;
			const myToken = ++fileToken;
			fileLoading.value = true;
			fileError.value = null;
			try {
				const result = await props.onLoadFile(pathRef.value, branchRef.value);
				if (myToken !== fileToken) return;
				const next = result?.content ?? "";
				content.value = next;
				emit("update:modelValue", next);
				if (result?.language) {
					languageRef.value = result.language;
					emit("update:language", result.language);
				}
			} catch (err) {
				if (myToken !== fileToken) return;
				fileError.value = err instanceof Error ? err.message : String(err);
			} finally {
				if (myToken === fileToken) fileLoading.value = false;
			}
		}
		watch([branchRef, pathRef], () => {
			loadFile();
		});
		const saving = ref(false);
		const saveError = ref(null);
		async function save() {
			if (!props.onSaveFile) return;
			if (!pathRef.value || !branchRef.value) return;
			saving.value = true;
			saveError.value = null;
			try {
				await props.onSaveFile(pathRef.value, branchRef.value, content.value);
			} catch (err) {
				saveError.value = err instanceof Error ? err.message : String(err);
			} finally {
				saving.value = false;
			}
		}
		const branchOptions = computed(() => {
			const all = new Set(branches.value);
			if (branchRef.value) all.add(branchRef.value);
			return Array.from(all);
		});
		const allErrors = computed(() => {
			const out = [...props.errors ?? []];
			if (fileError.value) out.push(fileError.value);
			if (saveError.value) out.push(saveError.value);
			return out;
		});
		const showSave = computed(() => Boolean(props.onSaveFile));
		onMounted(() => {
			loadBranches();
			loadFile();
		});
		__expose({
			reload: loadFile,
			save
		});
		return (_ctx, _cache) => {
			return openBlock(), createBlock(unref(FieldFrame_default), {
				label: __props.label,
				required: __props.required,
				"hide-label": __props.hideLabel,
				for: __props.id,
				"help-text": __props.helpText,
				errors: allErrors.value,
				class: normalizeClass(unref(cn)(props.classList))
			}, {
				default: withCtx(() => [createVNode(unref(Card_default), {
					"data-element-name": props.name ?? void 0,
					"data-testid": "git-code-editor"
				}, {
					default: withCtx(() => [createVNode(unref(CardHeader_default), { class: "flex flex-col gap-2 border-b py-3" }, {
						default: withCtx(() => [createElementVNode("div", _hoisted_1, [
							props.repository ? (openBlock(), createElementBlock("div", _hoisted_2, [createVNode(unref(GitBranch), { class: "size-3.5" }), createElementVNode("span", null, toDisplayString(props.repository), 1)])) : createCommentVNode("", true),
							createElementVNode("div", _hoisted_3, [createVNode(unref(Select_default), {
								"model-value": branchRef.value,
								disabled: __props.disabled || __props.readonly || branchesLoading.value,
								"onUpdate:modelValue": _cache[0] || (_cache[0] = (v) => updateBranch(String(v ?? "")))
							}, {
								default: withCtx(() => [createVNode(unref(SelectTrigger_default), {
									"data-testid": "git-code-editor-branch-trigger",
									"aria-label": "Branch"
								}, {
									default: withCtx(() => [createVNode(unref(SelectValue_default), { placeholder: "Select branch" })]),
									_: 1
								}), createVNode(unref(SelectContent_default), null, {
									default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(branchOptions.value, (b) => {
										return openBlock(), createBlock(unref(SelectItem_default), {
											key: b,
											value: b,
											"data-testid": `git-code-editor-branch-${b}`
										}, {
											default: withCtx(() => [createTextVNode(toDisplayString(b), 1)]),
											_: 2
										}, 1032, ["value", "data-testid"]);
									}), 128))]),
									_: 1
								})]),
								_: 1
							}, 8, ["model-value", "disabled"])]),
							createVNode(unref(Input_default), {
								"model-value": pathRef.value,
								placeholder: "path/to/file",
								class: "flex-1 min-w-48",
								disabled: __props.disabled || __props.readonly,
								"data-testid": "git-code-editor-path-input",
								"onUpdate:modelValue": updatePath
							}, null, 8, ["model-value", "disabled"]),
							showSave.value ? (openBlock(), createBlock(unref(Button_default), {
								key: 1,
								type: "button",
								variant: "default",
								size: "sm",
								disabled: saving.value || __props.disabled || __props.readonly || !pathRef.value || !branchRef.value,
								"data-testid": "git-code-editor-save",
								onClick: save
							}, {
								default: withCtx(() => [saving.value ? (openBlock(), createBlock(unref(Loader2), {
									key: 0,
									class: "size-4 animate-spin"
								})) : (openBlock(), createBlock(unref(Save), {
									key: 1,
									class: "size-4"
								})), createElementVNode("span", null, toDisplayString(saving.value ? "Saving…" : "Save"), 1)]),
								_: 1
							}, 8, ["disabled"])) : createCommentVNode("", true)
						]), languageRef.value ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(languageRef.value), 1)) : createCommentVNode("", true)]),
						_: 1
					}), createVNode(unref(CardContent_default), { class: "p-0" }, {
						default: withCtx(() => [fileLoading.value ? (openBlock(), createElementBlock("div", _hoisted_5, [createVNode(unref(Loader2), { class: "size-4 animate-spin" }), _cache[1] || (_cache[1] = createElementVNode("span", null, "Loading file…", -1))])) : createCommentVNode("", true), createVNode(unref(Textarea_default), {
							id: __props.id,
							"model-value": content.value,
							readonly: __props.readonly || fileLoading.value,
							disabled: __props.disabled,
							required: __props.required,
							rows: 16,
							spellcheck: "false",
							class: "min-h-64 rounded-none border-0 font-mono text-xs focus-visible:ring-0 focus-visible:ring-offset-0",
							"data-element-name": props.name ?? void 0,
							"data-testid": "git-code-editor-textarea",
							"onUpdate:modelValue": updateContent
						}, null, 8, [
							"id",
							"model-value",
							"readonly",
							"disabled",
							"required",
							"data-element-name"
						])]),
						_: 1
					})]),
					_: 1
				}, 8, ["data-element-name"])]),
				_: 1
			}, 8, [
				"label",
				"required",
				"hide-label",
				"for",
				"help-text",
				"errors",
				"class"
			]);
		};
	}
});
//#endregion
//#region src/components/compositions/elements/code/GitCodeEditor.vue
var GitCodeEditor_exports = /* @__PURE__ */ __exportAll({ default: () => GitCodeEditor_default });
var GitCodeEditor_default = GitCodeEditor_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { GitCodeEditor_exports as n, GitCodeEditor_default as t };

//# sourceMappingURL=GitCodeEditor-B6ZloqYu.js.map