import useXComponentConfig from "../_utils/hooks/use-x-component-config.js";
import { provideActionButtonContext } from "./components/ActionButton.js";
import ClearButton_default from "./components/ClearButton.js";
import LoadingButton_default from "./components/LoadingButton/index.js";
import SendButton_default from "./components/SendButton.js";
import { provideSenderContext } from "./context.js";
import SlotTextArea_default from "./components/SlotTextArea.js";
import SpeechButton_default from "./components/SpeechButton/index.js";
import TextArea_default from "./components/TextArea.js";
import useSpeech from "./hooks/use-speech.js";
import style_default from "./style/index.js";
import { computed, createVNode, defineComponent, mergeProps, ref, useAttrs, watch } from "vue";
import { useConfig } from "antdv-next/config-provider/context";
import { Flex } from "antdv-next";
//#region components/sender/Sender.tsx
var sharedRenderComponents = {
	SendButton: SendButton_default,
	ClearButton: ClearButton_default,
	LoadingButton: LoadingButton_default,
	SpeechButton: SpeechButton_default
};
var Sender_default = /* @__PURE__ */ defineComponent({
	name: "AxSender",
	inheritAttrs: false,
	props: {
		prefixCls: {
			type: String,
			default: "antd-sender"
		},
		rootClass: {
			type: String,
			default: void 0
		},
		class: {
			type: String,
			default: void 0
		},
		style: {
			type: [
				String,
				Object,
				Array
			],
			default: void 0
		},
		defaultValue: {
			type: String,
			default: ""
		},
		value: {
			type: String,
			default: void 0
		},
		loading: {
			type: Boolean,
			default: false
		},
		readOnly: {
			type: Boolean,
			default: false
		},
		submitType: {
			type: String,
			default: "enter"
		},
		disabled: {
			type: Boolean,
			default: false
		},
		slotConfig: {
			type: Array,
			default: void 0
		},
		skill: {
			type: Object,
			default: void 0
		},
		placeholder: {
			type: String,
			default: void 0
		},
		allowSpeech: {
			type: [Boolean, Object],
			default: void 0
		},
		autoSize: {
			type: [Boolean, Object],
			default: () => ({ maxRows: 8 })
		},
		classNames: {
			type: Object,
			default: () => ({})
		},
		styles: {
			type: Object,
			default: () => ({})
		},
		prefix: {
			type: [
				Object,
				Function,
				Boolean
			],
			default: void 0
		},
		suffix: {
			type: [
				Object,
				Function,
				Boolean
			],
			default: void 0
		},
		header: {
			type: [
				Object,
				Function,
				Boolean
			],
			default: void 0
		},
		footer: {
			type: [
				Object,
				Function,
				Boolean
			],
			default: void 0
		},
		onSubmit: {
			type: Function,
			default: void 0
		},
		onChange: {
			type: Function,
			default: void 0
		},
		onCancel: {
			type: Function,
			default: void 0
		},
		onKeyDown: {
			type: Function,
			default: void 0
		},
		onKeyUp: {
			type: Function,
			default: void 0
		},
		onPaste: {
			type: Function,
			default: void 0
		},
		onPasteFile: {
			type: Function,
			default: void 0
		},
		onFocus: {
			type: Function,
			default: void 0
		},
		onBlur: {
			type: Function,
			default: void 0
		}
	},
	emits: ["update:value"],
	setup(props, { expose, slots, emit }) {
		const attrs = useAttrs();
		const configCtx = useConfig();
		const contextConfig = useXComponentConfig("sender");
		const prefixCls = computed(() => configCtx.value.getPrefixCls?.("sender", props.prefixCls) ?? props.prefixCls);
		const direction = computed(() => configCtx.value.direction);
		const [hashId, cssVarCls] = style_default(prefixCls);
		const containerRef = ref();
		const inputRef = ref();
		const isSlotMode = computed(() => Array.isArray(props.slotConfig) || !!props.skill?.value);
		const innerValue = ref(props.defaultValue);
		const mergedValue = computed(() => props.value ?? innerValue.value);
		const triggerValueChange = (nextValue, event, slotConfig, skill) => {
			innerValue.value = nextValue;
			emit("update:value", nextValue);
			props.onChange?.(nextValue, event, slotConfig, skill);
		};
		const submitDisabled = ref(!mergedValue.value);
		watch(() => mergedValue.value, (next) => {
			if (!isSlotMode.value) submitDisabled.value = !next;
		}, { immediate: true });
		const [speechPermission, triggerSpeech, speechRecording] = useSpeech((transcript) => {
			if (isSlotMode.value) {
				inputRef.value?.insert?.([{
					type: "text",
					value: transcript
				}]);
				return;
			}
			triggerValueChange(`${mergedValue.value} ${transcript}`);
		}, () => props.allowSpeech);
		const triggerSend = () => {
			if (!props.onSubmit || props.loading || submitDisabled.value) return;
			const value = inputRef.value?.getValue?.() ?? { value: "" };
			const slotConfig = "slotConfig" in value ? value.slotConfig : void 0;
			const skill = "skill" in value ? value.skill : void 0;
			props.onSubmit(value.value, slotConfig, skill);
		};
		const triggerClear = () => {
			if (inputRef.value?.clear) {
				inputRef.value.clear();
				return;
			}
			triggerValueChange("");
		};
		expose({
			get nativeElement() {
				return containerRef.value;
			},
			focus(options) {
				inputRef.value?.focus(options);
			},
			blur() {
				inputRef.value?.blur();
			},
			clear() {
				triggerClear();
			},
			insert(text, position) {
				if (isSlotMode.value) {
					const slotList = Array.isArray(text) ? text : [{
						type: "text",
						value: text
					}];
					inputRef.value?.insert?.(slotList, position);
					return;
				}
				const textValue = Array.isArray(text) ? text.map((config) => {
					if (config.type === "text") return config.value ?? "";
					return config.formatResult?.(config.props?.defaultValue) ?? "";
				}).join("") : text;
				inputRef.value?.insert?.(textValue, position);
			},
			getValue() {
				return inputRef.value?.getValue() ?? { value: "" };
			}
		});
		provideSenderContext(computed(() => ({
			value: mergedValue.value,
			onChange: triggerValueChange,
			onKeyUp: props.onKeyUp,
			onKeyDown: props.onKeyDown,
			onPaste: props.onPaste,
			onPasteFile: props.onPasteFile,
			disabled: props.disabled,
			readOnly: props.readOnly,
			submitType: props.submitType,
			prefixCls: prefixCls.value,
			styles: props.styles,
			classNames: props.classNames,
			autoSize: props.autoSize,
			triggerSend,
			placeholder: props.placeholder,
			onFocus: props.onFocus,
			onBlur: props.onBlur,
			slotConfig: props.slotConfig,
			skill: props.skill,
			setSubmitDisabled: (disabled) => {
				submitDisabled.value = disabled;
			}
		})));
		const actionBtnCls = computed(() => `${prefixCls.value}-actions-btn`);
		provideActionButtonContext(computed(() => ({
			prefixCls: actionBtnCls.value,
			onSend: triggerSend,
			onSendDisabled: submitDisabled.value,
			onClear: triggerClear,
			onClearDisabled: submitDisabled.value,
			onCancel: props.onCancel,
			onCancelDisabled: !props.loading,
			onSpeech: () => triggerSpeech(false),
			onSpeechDisabled: !speechPermission.value,
			speechRecording: speechRecording.value,
			disabled: props.disabled
		})));
		const renderNode = (node, slotName, defaultNode) => {
			if (slots[slotName]) return slots[slotName]?.({
				defaultNode,
				components: sharedRenderComponents
			});
			if (typeof node === "function") return node(defaultNode, { components: sharedRenderComponents });
			if (node || node === false) return node;
			return null;
		};
		return () => {
			const cls = prefixCls.value;
			const actionListCls = `${cls}-actions-list`;
			const actionNode = createVNode(Flex, { "class": `${actionListCls}-presets` }, { default: () => [props.allowSpeech && createVNode(SpeechButton_default, null, null), props.loading ? createVNode(LoadingButton_default, null, null) : createVNode(SendButton_default, null, null)] });
			const suffixNode = renderNode(props.suffix, "suffix", actionNode) ?? actionNode;
			const prefixNode = renderNode(props.prefix, "prefix", actionNode);
			const headerNode = renderNode(props.header, "header", actionNode);
			const footerNode = renderNode(props.footer, "footer", actionNode);
			return createVNode("div", mergeProps({
				"ref": containerRef,
				"class": [
					cls,
					contextConfig.value.classes?.root,
					props.class,
					props.rootClass,
					props.classNames.root,
					hashId.value,
					cssVarCls.value,
					`${cls}-main`,
					{
						[`${cls}-rtl`]: direction.value === "rtl",
						[`${cls}-disabled`]: props.disabled
					}
				],
				"style": [
					contextConfig.value.style,
					props.style,
					contextConfig.value.styles?.root,
					props.styles.root
				]
			}, attrs), [
				headerNode,
				createVNode("div", {
					"class": [`${cls}-content`, props.classNames.content],
					"style": props.styles.content,
					"onMousedown": (e) => {
						const inputNode = containerRef.value?.querySelector(`.${cls}-input`);
						if (!isSlotMode.value && e.target !== inputNode) e.preventDefault();
						if (e.target === inputNode || e.target === containerRef.value) inputRef.value?.focus();
					}
				}, [
					prefixNode && createVNode("div", {
						"class": [
							`${cls}-prefix`,
							contextConfig.value.classes?.prefix,
							props.classNames.prefix
						],
						"style": [contextConfig.value.styles?.prefix, props.styles.prefix]
					}, [prefixNode]),
					isSlotMode.value ? createVNode(SlotTextArea_default, { "ref": inputRef }, null) : createVNode(TextArea_default, { "ref": inputRef }, null),
					suffixNode && createVNode("div", {
						"class": [
							actionListCls,
							contextConfig.value.classes?.suffix,
							props.classNames.suffix
						],
						"style": [contextConfig.value.styles?.suffix, props.styles.suffix]
					}, [suffixNode])
				]),
				footerNode && createVNode("div", {
					"class": [
						`${cls}-footer`,
						contextConfig.value.classes?.footer,
						props.classNames.footer
					],
					"style": [contextConfig.value.styles?.footer, props.styles.footer]
				}, [footerNode])
			]);
		};
	}
});
//#endregion
export { Sender_default as default };
