import * as React from 'react';
import './cn-sender.scss';
import SlotTextArea from './compoments/slot-text-area';
import { ActionButtonContext, SenderContext, SendHeaderContext } from './context';
import useProxyImperativeHandle from './hooks/use-proxy-imperative-handle';
import clsx from 'classnames';
import useControlledState from './hooks/use-controlled-state';
import SendButton from './compoments/send-button';
import LoadingButton from './compoments/LoadingButton';
import RecordButton from './compoments/record-button';
import useRecord, { RECORD_STATUS } from './hooks/use-record';
import { v4 as uuidv4 } from 'uuid';
/** Used for actions render needed components */
const ForwardSender = React.forwardRef((props, ref) => {
    const { prefixCls: customizePrefixCls, styles = {}, classNames = {}, className, rootClassName, style, defaultValue, value, slotConfig, schema, readOnly, submitType = 'enter', onSubmit, loading, components, onCancel, onChange, suffix, onKeyUp, onKeyDown, disabled, allowRecord, onRecordMessage, prefix, footer, header, onPaste, onPasteFile, autoSize = { maxRows: 8 }, placeholder, onFocus, onBlur, skill, popupTriggerKey = '/', // 新增，默认值为 "/"
    customPopupProps, // 新增
    sendButtonProps, // 新增：发送按钮配置
    canEmptySubmit = false, // 新增：是否允许内容为空时提交
    ...restProps } = props;
    // const id = React.useId();
    const isSlotMode = Array.isArray(slotConfig) || (skill === null || skill === void 0 ? void 0 : skill.value);
    // ============================= MISC =============================
    // ============================= Refs =============================
    const containerRef = React.useRef(null);
    const inputRef = React.useRef(null);
    useProxyImperativeHandle(ref, () => {
        var _a;
        return {
            nativeElement: containerRef.current,
            inputElement: (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.nativeElement,
            focus: (options) => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(options); },
            blur: () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur(); },
            insert: (...args) => { var _a, _b; return (_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.insert) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
            clear: () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.clear(); },
            getValue: () => {
                var _a, _b;
                return (_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.getValue()) !== null && _b !== void 0 ? _b : {
                    value: '',
                    slotConfig: [],
                    formValue: {},
                    skill: undefined,
                };
            },
        };
    });
    const mergedCls = clsx(className, rootClassName, classNames.root, 'cn-sender-main', {
        [`cn-sender-disabled`]: disabled,
    });
    // ============================ Action List Class =============================
    const prefixCls = 'cn-sender';
    const actionListCls = `${prefixCls}-actions-list`;
    const actionBtnCls = `${prefixCls}-actions-btn`;
    // ============================ Value =============================
    const [innerValue, setInnerValue] = useControlledState(defaultValue || '', value);
    // ============================ Action context Data ============================
    const [submitDisabled, setSubmitDisabled] = React.useState(!innerValue);
    const triggerValueChange = (nextValue, event, slotConfigParam, skillParam) => {
        setInnerValue(nextValue);
        onChange === null || onChange === void 0 ? void 0 : onChange(nextValue, event, slotConfigParam !== null && slotConfigParam !== void 0 ? slotConfigParam : [], skillParam);
    };
    // ============================ Record ============================
    // 保存上一次录音的文本，用于计算增量
    const lastRecordTextRef = React.useRef('');
    // 录音功能（仅在 allowRecord 为 true 时启用）
    const recordInfo = useRecord({
        onRecordMessage: (param) => {
            if (param.method === 'setInputText') {
                // 将录音转文字后的文本填充到输入框
                if (inputRef.current && param.text) {
                    const currentText = lastRecordTextRef.current;
                    // 计算增量文本（新增的部分）
                    const incrementalText = param.text.slice(currentText.length);
                    if (incrementalText) {
                        // 在输入框末尾插入增量文本
                        inputRef.current.insert([{ type: 'text', value: incrementalText }], 'end');
                    }
                    // 更新保存的文本
                    lastRecordTextRef.current = param.text;
                }
                // 调用外部回调
                onRecordMessage === null || onRecordMessage === void 0 ? void 0 : onRecordMessage(param);
            }
        },
    });
    // 处理录音按钮点击
    const handleRecordClick = React.useCallback(() => {
        if (recordInfo.recordStatus === RECORD_STATUS.RECORDING) {
            recordInfo.stopRecord();
            // 停止录音时，重置保存的文本
            lastRecordTextRef.current = '';
        }
        else {
            // 开始录音时，重置保存的文本
            lastRecordTextRef.current = '';
            recordInfo.startRecord({ fillMode: 'input', conversationId: uuidv4() });
        }
    }, [recordInfo]);
    // ============================ Record ============================
    // const [recordPermission, triggerRecord, recordRecording] = useRecord((transcript) => {
    //   if (isSlotMode) {
    //     (inputRef.current as SlotTextAreaRef)?.insert?.([
    //       {
    //         type: 'text',
    //         value: transcript,
    //       },
    //     ]);
    //   } else {
    //     triggerValueChange(`${innerValue} ${transcript}`);
    //   }
    // }, allowRecord);
    // ============================ Events ============================
    const triggerSend = React.useCallback(() => {
        if ((inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) && onSubmit && !loading && !submitDisabled) {
            const inputValue = inputRef.current.getValue();
            // 转换为 searchTokenList 并打印（如果存在 slotConfig 和 formValue）
            // if (inputValue?.slotConfig && inputValue?.formValue) {
            //   const tokens = convertToSearchTokenList(inputValue.slotConfig, inputValue.formValue);
            // }
            onSubmit(inputValue.value, inputValue.slotConfig, inputValue.skill, inputValue.formValue);
        }
    }, [onSubmit, loading, submitDisabled]);
    const triggerClear = () => {
        var _a, _b;
        triggerValueChange('');
        if (isSlotMode) {
            (_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.clear) === null || _b === void 0 ? void 0 : _b.call(_a);
        }
    };
    // ============================ Action ============================
    const actionNode = (
    // <>操作按钮</>
    React.createElement("div", { className: `${actionListCls}-presets` },
        allowRecord && (React.createElement(RecordButton, { isRecording: recordInfo.recordStatus === RECORD_STATUS.RECORDING, onRecordClick: handleRecordClick, disabled: readOnly || disabled })),
        loading ? React.createElement(LoadingButton, null) : React.createElement(SendButton, null)));
    // ============================ Suffix ============================
    let suffixNode = actionNode;
    if (typeof suffix === 'function') {
        suffixNode = suffix(actionNode, {
        // components: sharedRenderComponents,
        });
    }
    else if (suffix || suffix === false) {
        suffixNode = suffix;
    }
    // ============================ Prefix ============================
    const prefixNode = typeof prefix === 'function'
        ? prefix(actionNode, {
        // components: sharedRenderComponents
        })
        : prefix || null;
    // ============================ Header ============================
    const headerNode = typeof header === 'function'
        ? header(actionNode, {
        // components: sharedRenderComponents
        })
        : header || null;
    // ============================ Footer ============================
    const footerNode = typeof footer === 'function'
        ? footer(actionNode, {
        // components: sharedRenderComponents
        })
        : footer || null;
    // Custom actions context props
    const actionsContextProps = {
        prefixCls: actionBtnCls,
        onSend: triggerSend,
        // 如果允许空提交，则不禁用；否则当内容为空时禁用
        onSendDisabled: canEmptySubmit ? false : !innerValue,
        onClear: triggerClear,
        onClearDisabled: !innerValue,
        onCancel,
        onCancelDisabled: !loading,
        // onSpeech: () => triggerSpeech(false),
        // onSpeechDisabled: !speechPermission,
        // speechRecording,
        disabled,
        setSubmitDisabled,
        sendButtonProps, // 传递发送按钮配置
        canEmptySubmit, // 传递是否允许空提交
    };
    // ============================ Context ============================
    const contextValue = React.useMemo(() => ({
        value: innerValue,
        onChange: triggerValueChange,
        slotConfig,
        schema,
        onKeyUp,
        onKeyDown,
        onPaste,
        onPasteFile,
        disabled,
        readOnly,
        submitType,
        styles,
        classNames,
        autoSize,
        components,
        triggerSend,
        placeholder,
        onFocus,
        onBlur,
        skill,
        popupTriggerKey, // 新增
        customPopupProps, // 新增
        containerRef, // 弹层挂载容器，运行态下保证弹窗定位正确
        ...restProps,
    }), [
        innerValue,
        triggerValueChange,
        slotConfig,
        schema,
        onKeyUp,
        onKeyDown,
        onPaste,
        onPasteFile,
        disabled,
        readOnly,
        submitType,
        styles,
        classNames,
        autoSize,
        components,
        triggerSend,
        placeholder,
        onFocus,
        onBlur,
        skill,
        popupTriggerKey, // 新增
        customPopupProps, // 新增
        containerRef,
        restProps,
    ]);
    // ============================ Focus =============================
    const onContentMouseDown = () => {
        // If input focused but click on the container,
        // input will lose focus.
        // We call `preventDefault` to prevent this behavior
        // if (!isSlotMode && e.target !== containerRef.current?.querySelector(`.${inputCls}`)) {
        //   e.preventDefault();
        // }
        // if (e.target === containerRef.current?.querySelector(`.${inputCls}`)) {
        //   inputRef.current?.focus();
        // }
    };
    // ============================ Render ============================
    return (React.createElement("div", { 
        // key={id}
        ref: containerRef, className: mergedCls, style: {
            ...style,
            ...styles.root,
        } },
        React.createElement(SenderContext.Provider, { value: contextValue },
            React.createElement(ActionButtonContext.Provider, { value: actionsContextProps },
                headerNode && (React.createElement(SendHeaderContext.Provider, { value: { prefixCls } }, headerNode)),
                React.createElement("div", { className: clsx(`${prefixCls}-content`, classNames.content), style: styles.content, onMouseDown: onContentMouseDown },
                    prefixNode && React.createElement("div", null, prefixNode),
                    React.createElement(SlotTextArea, { ref: inputRef }),
                    suffixNode && (React.createElement("div", { className: clsx(actionListCls, classNames.suffix), style: styles.suffix }, suffixNode))),
                footerNode && (React.createElement("div", { className: clsx(`cn-sender-footer`, classNames.footer) }, footerNode))))));
});
ForwardSender.displayName = 'ForwardSender';
export const CnSender = ForwardSender;
CnSender.displayName = 'CnSender';
