import warning from "../../_utils/warning.js";
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
//#region components/sender/hooks/use-speech.ts
function useSpeech(onSpeech, allowSpeech) {
	const permissionState = ref(null);
	const recording = ref(false);
	let recognition = null;
	let forceBreak = false;
	const speechConfig = computed(() => {
		const val = allowSpeech?.();
		if (typeof val === "object") return val;
		return null;
	});
	const isControlled = computed(() => typeof speechConfig.value?.recording === "boolean");
	let permissionStatus = null;
	onMounted(() => {
		if (!isControlled.value && "permissions" in navigator) navigator.permissions.query({ name: "microphone" }).then((status) => {
			permissionState.value = status.state;
			status.onchange = function() {
				permissionState.value = this.state;
			};
			permissionStatus = status;
		}).catch((error) => {
			warning(false, "Sender", `Browser does not support querying microphone permission. ${error instanceof Error ? error.message : String(error)}`);
		});
	});
	onBeforeUnmount(() => {
		if (permissionStatus) permissionStatus.onchange = null;
	});
	const getSpeechRecognition = () => {
		if (typeof window === "undefined") return null;
		return window.SpeechRecognition || window.webkitSpeechRecognition || null;
	};
	const mergedAllowSpeech = computed(() => !!(isControlled.value || getSpeechRecognition() && permissionState.value !== "denied"));
	const ensureRecognition = () => {
		if (!mergedAllowSpeech.value || recognition) return;
		const SpeechRecognitionCtor = getSpeechRecognition();
		if (!SpeechRecognitionCtor) return;
		recognition = new SpeechRecognitionCtor();
		recognition.onstart = () => {
			recording.value = true;
		};
		recognition.onend = () => {
			recording.value = false;
		};
		recognition.onresult = (event) => {
			if (!forceBreak) {
				const transcript = event.results?.[0]?.[0]?.transcript;
				onSpeech(transcript);
			}
			forceBreak = false;
		};
	};
	const triggerSpeech = (doForceBreak) => {
		if (doForceBreak && !recording.value) return;
		forceBreak = doForceBreak;
		if (isControlled.value) {
			speechConfig.value?.onRecordingChange(!recording.value);
			return;
		}
		ensureRecognition();
		if (!recognition) return;
		if (recording.value) {
			recognition.stop();
			speechConfig.value?.onRecordingChange?.(false);
		} else {
			recognition.start();
			speechConfig.value?.onRecordingChange?.(true);
		}
	};
	return [
		mergedAllowSpeech,
		triggerSpeech,
		recording
	];
}
//#endregion
export { useSpeech as default };
