import { computed, ref } from "vue";
import { defineStore } from "pinia";
//#region src/stores/quizBuilderStore.ts
var idCounter = 0;
function nextId(prefix) {
	idCounter += 1;
	return `${prefix}-${Date.now()}-${idCounter}`;
}
/** Test helper to make ids deterministic. */
function __resetQuizBuilderIdCounter() {
	idCounter = 0;
}
function emptySchema() {
	return {
		questionBanks: [{
			id: nextId("bank"),
			name: "Default bank"
		}],
		questions: []
	};
}
/**
* Produce the type-specific default fields for a brand-new question of
* `type`. Generic fields like `id`, `bankId`, `points`, `required` are
* added by the caller.
*/
function defaultsForType(type) {
	const base = {
		prompt: `New ${type.replace(/-/g, " ")} question`,
		options: []
	};
	switch (type) {
		case "single-choice":
		case "multiple-choice": return {
			...base,
			options: [{
				id: nextId("opt"),
				label: "Option A",
				value: "a"
			}, {
				id: nextId("opt"),
				label: "Option B",
				value: "b"
			}],
			...type === "multiple-choice" ? { allowPartialCredit: true } : {}
		};
		case "true-false": return {
			...base,
			correctAnswer: true
		};
		case "text-match": return {
			...base,
			correctAnswers: [""],
			caseSensitive: false,
			trimWhitespace: true
		};
		case "numeric-range": return {
			...base,
			correctAnswer: 0,
			tolerance: 0
		};
		case "essay": return base;
		case "matching": return {
			...base,
			matchPairs: [{
				left: "",
				right: ""
			}, {
				left: "",
				right: ""
			}],
			shuffleMatches: true
		};
		case "ordering": return {
			...base,
			correctOrder: ["", ""]
		};
		case "fill-blank": return {
			...base,
			blanks: [{
				id: nextId("blank"),
				answers: [""]
			}],
			caseSensitive: false
		};
		case "matching-categories": return {
			...base,
			categories: [{
				slug: nextId("cat"),
				label: "",
				items: [
					"",
					"",
					"",
					""
				]
			}, {
				slug: nextId("cat"),
				label: "",
				items: [
					"",
					"",
					"",
					""
				]
			}],
			itemsPerCategory: 4
		};
		case "ai-analysis": return {
			...base,
			scoringMethod: "standard",
			aiPrompt: "",
			aiCriteria: [{
				key: nextId("crit"),
				name: "",
				description: "",
				points: 100
			}],
			pointsPerItem: 50,
			maxPoints: 100,
			confidenceThreshold: .75,
			aiModel: ""
		};
	}
}
/** Fields preserved when a question's type changes. */
var PRESERVED_KEYS = [
	"prompt",
	"helpText",
	"hint",
	"icon",
	"required",
	"points",
	"timeLimit",
	"feedback"
];
var useQuizBuilderStore = defineStore("gx-modui/quizBuilder", () => {
	const builders = ref({});
	const selections = ref({});
	function ensureBuilder(builderId) {
		if (!builders.value[builderId]) {
			builders.value[builderId] = emptySchema();
			selections.value[builderId] = { id: null };
		}
		return builders.value[builderId];
	}
	/**
	* Load an external schema. Tolerates legacy shapes — if `questionBanks`
	* is empty or missing, a default bank is created and any orphan
	* questions are assigned to it.
	*/
	function loadSchema(builderId, schema) {
		const incomingBanks = (schema.questionBanks ?? []).map((b) => ({ ...b }));
		const banks = incomingBanks.length > 0 ? incomingBanks : [{
			id: nextId("bank"),
			name: "Default bank"
		}];
		const defaultBankId = banks[0].id;
		const validBankIds = new Set(banks.map((b) => b.id));
		const questions = (schema.questions ?? []).map((q) => ({
			...q,
			bankId: q.bankId && validBankIds.has(q.bankId) ? q.bankId : defaultBankId,
			options: (q.options ?? []).map((o) => ({ ...o }))
		}));
		builders.value[builderId] = {
			questionBanks: banks,
			questions
		};
		selections.value[builderId] = { id: null };
	}
	function resetBuilder(builderId) {
		delete builders.value[builderId];
		delete selections.value[builderId];
	}
	/**
	* Append a fresh question of `type` to `bankId`. Type-specific
	* fields are seeded by `defaultsForType`. Returns the new id.
	*/
	function addQuestion(builderId, type, bankId) {
		const schema = ensureBuilder(builderId);
		const id = nextId(`q-${type}`);
		const question = {
			id,
			bankId,
			type,
			required: false,
			...defaultsForType(type)
		};
		schema.questions = [...schema.questions, question];
		return id;
	}
	/** Remove a question by id. */
	function removeQuestion(builderId, questionId) {
		const schema = ensureBuilder(builderId);
		schema.questions = schema.questions.filter((q) => q.id !== questionId);
		if (selections.value[builderId]?.id === questionId) selections.value[builderId] = { id: null };
	}
	/**
	* Patch a question's properties. When `patch.type` changes the
	* type, type-specific fields are reseeded and generic fields
	* (prompt, helpText, points, …) are preserved.
	*/
	function updateQuestion(builderId, questionId, patch) {
		const schema = ensureBuilder(builderId);
		const idx = schema.questions.findIndex((q) => q.id === questionId);
		if (idx < 0) return;
		const current = schema.questions[idx];
		let merged;
		if (patch.type && patch.type !== current.type) {
			const preserved = {};
			for (const key of PRESERVED_KEYS) if (current[key] !== void 0) preserved[key] = current[key];
			const defaults = defaultsForType(patch.type);
			merged = {
				id: current.id,
				bankId: current.bankId,
				type: patch.type,
				...defaults,
				...preserved,
				...patch
			};
		} else merged = {
			...current,
			...patch
		};
		const next = [...schema.questions];
		next[idx] = merged;
		schema.questions = next;
	}
	/** Append a new empty option to a question. Returns the option id. */
	function addOption(builderId, questionId) {
		const schema = ensureBuilder(builderId);
		const idx = schema.questions.findIndex((q) => q.id === questionId);
		if (idx < 0) return "";
		const current = schema.questions[idx];
		const optId = nextId("opt");
		const newOption = {
			id: optId,
			label: `Option ${String.fromCharCode(65 + current.options.length)}`,
			value: ""
		};
		const next = [...schema.questions];
		next[idx] = {
			...current,
			options: [...current.options, newOption]
		};
		schema.questions = next;
		return optId;
	}
	/** Remove an option from a question. */
	function removeOption(builderId, questionId, optionId) {
		const schema = ensureBuilder(builderId);
		const idx = schema.questions.findIndex((q) => q.id === questionId);
		if (idx < 0) return;
		const current = schema.questions[idx];
		const next = [...schema.questions];
		next[idx] = {
			...current,
			options: current.options.filter((o) => o.id !== optionId)
		};
		schema.questions = next;
	}
	/** Patch an option's properties. */
	function updateOption(builderId, questionId, optionId, patch) {
		const schema = ensureBuilder(builderId);
		const idx = schema.questions.findIndex((q) => q.id === questionId);
		if (idx < 0) return;
		const current = schema.questions[idx];
		const optIdx = current.options.findIndex((o) => o.id === optionId);
		if (optIdx < 0) return;
		const nextOptions = [...current.options];
		nextOptions[optIdx] = {
			...nextOptions[optIdx],
			...patch
		};
		if (patch.correct === true && current.type === "single-choice") {
			for (let i = 0; i < nextOptions.length; i++) if (i !== optIdx) nextOptions[i] = {
				...nextOptions[i],
				correct: false
			};
		}
		const next = [...schema.questions];
		next[idx] = {
			...current,
			options: nextOptions
		};
		schema.questions = next;
	}
	/** Create a fresh question bank. Returns the new bank id. */
	function addBank(builderId, name) {
		const schema = ensureBuilder(builderId);
		const id = nextId("bank");
		const banks = schema.questionBanks;
		const bank = {
			id,
			name: name ?? `Bank ${banks.length + 1}`
		};
		builders.value[builderId] = {
			...schema,
			questionBanks: [...banks, bank]
		};
		return id;
	}
	/**
	* Remove a bank by id along with any questions inside it. Refuses
	* to remove the last remaining bank — the schema must always have
	* at least one bank.
	*/
	function removeBank(builderId, bankId) {
		const schema = ensureBuilder(builderId);
		if (schema.questionBanks.length <= 1) return;
		const sel = selections.value[builderId];
		builders.value[builderId] = {
			...schema,
			questionBanks: schema.questionBanks.filter((b) => b.id !== bankId),
			questions: schema.questions.filter((q) => q.bankId !== bankId)
		};
		if (sel?.id) {
			if (!builders.value[builderId].questions.some((q) => q.id === sel.id)) selections.value[builderId] = { id: null };
		}
	}
	/** Patch a bank's properties (name, description). */
	function updateBank(builderId, bankId, patch) {
		const schema = ensureBuilder(builderId);
		const banks = schema.questionBanks;
		const idx = banks.findIndex((b) => b.id === bankId);
		if (idx < 0) return;
		const next = [...banks];
		next[idx] = {
			...next[idx],
			...patch
		};
		builders.value[builderId] = {
			...schema,
			questionBanks: next
		};
	}
	/**
	* Duplicate a question (with fresh id + fresh option ids), placing
	* the copy at the end of the same bank — or `toBankId` when given.
	* Returns the new question id.
	*/
	function copyQuestion(builderId, questionId, toBankId) {
		const schema = ensureBuilder(builderId);
		const source = schema.questions.find((q) => q.id === questionId);
		if (!source) return "";
		const newId = nextId(`q-${source.type}`);
		const copy = {
			...source,
			id: newId,
			bankId: toBankId ?? source.bankId,
			options: source.options.map((o) => ({
				...o,
				id: nextId("opt")
			}))
		};
		schema.questions = [...schema.questions, copy];
		return newId;
	}
	/**
	* Move a question to a different index within its bank. `toIndex`
	* is relative to questions in the same bank; questions in other
	* banks retain their relative order.
	*/
	function reorderQuestionInBank(builderId, bankId, questionId, toIndex) {
		const schema = ensureBuilder(builderId);
		const target = schema.questions.find((q) => q.id === questionId);
		if (!target || target.bankId !== bankId) return;
		const inScopeIds = schema.questions.filter((q) => q.bankId === bankId).map((q) => q.id);
		const fromIdx = inScopeIds.indexOf(questionId);
		if (fromIdx < 0) return;
		const clamped = Math.max(0, Math.min(toIndex, inScopeIds.length - 1));
		if (clamped === fromIdx) return;
		inScopeIds.splice(fromIdx, 1);
		inScopeIds.splice(clamped, 0, questionId);
		let cursor = 0;
		const next = [];
		for (const q of schema.questions) if (q.bankId === bankId) {
			const nextQId = inScopeIds[cursor];
			cursor += 1;
			const replacement = schema.questions.find((qq) => qq.id === nextQId);
			next.push(replacement);
		} else next.push(q);
		schema.questions = next;
	}
	function select(builderId, id) {
		selections.value[builderId] = { id };
	}
	function getSelection(builderId) {
		return selections.value[builderId] ?? { id: null };
	}
	function getSchema(builderId) {
		return ensureBuilder(builderId);
	}
	return {
		builders,
		selections,
		ensureBuilder,
		loadSchema,
		resetBuilder,
		addQuestion,
		removeQuestion,
		updateQuestion,
		addOption,
		removeOption,
		updateOption,
		addBank,
		removeBank,
		updateBank,
		copyQuestion,
		reorderQuestionInBank,
		select,
		getSelection,
		getSchema
	};
});
/** Composable wrapping store access for a single builder instance. */
function useQuizBuilder(builderId) {
	const store = useQuizBuilderStore();
	store.ensureBuilder(builderId);
	return {
		schema: computed(() => store.getSchema(builderId)),
		selection: computed(() => store.getSelection(builderId)),
		addQuestion: (type, bankId) => store.addQuestion(builderId, type, bankId),
		removeQuestion: (id) => store.removeQuestion(builderId, id),
		updateQuestion: (id, patch) => store.updateQuestion(builderId, id, patch),
		addOption: (questionId) => store.addOption(builderId, questionId),
		removeOption: (questionId, optionId) => store.removeOption(builderId, questionId, optionId),
		updateOption: (questionId, optionId, patch) => store.updateOption(builderId, questionId, optionId, patch),
		addBank: (name) => store.addBank(builderId, name),
		removeBank: (bankId) => store.removeBank(builderId, bankId),
		updateBank: (bankId, patch) => store.updateBank(builderId, bankId, patch),
		copyQuestion: (questionId, toBankId) => store.copyQuestion(builderId, questionId, toBankId),
		reorderQuestionInBank: (bankId, questionId, toIndex) => store.reorderQuestionInBank(builderId, bankId, questionId, toIndex),
		select: (id) => store.select(builderId, id),
		loadSchema: (schema) => store.loadSchema(builderId, schema),
		reset: () => store.resetBuilder(builderId)
	};
}
//#endregion
export { useQuizBuilder as n, useQuizBuilderStore as r, __resetQuizBuilderIdCounter as t };

//# sourceMappingURL=quizBuilderStore-DF5Qdr3i.js.map