/**
 * ============================================================
 *  src/ui/hooks/usePasteHandler.ts —— 粘贴检测 Hook（v0.3 最终版）
 * ------------------------------------------------------------
 *  功能：
 *    1. 检测粘贴输入（通过内容长度阈值）
 *    2. 收集多 Chunk 粘贴内容（处理 stdin 分块到达）
 *    3. ✨ 粘贴期间拦截所有 Enter（防止多行内容被误发送）
 *    4. 跨平台兼容：Win / Mac / Linux
 *
 *  v0.3 核心设计原则（符合用户直觉）：
 *    - Enter（单独按）：始终返回 'continue' → 调用方处理为**发送消息**
 *    - Alt+Enter（Mac: Option+Enter）：返回 'enter-newline' → 调用方处理为**插入换行**
 *    - Ctrl+Enter：返回 'continue' → 调用方处理为**强制发送**
 *    - 粘贴期间 + 任何 Enter：返回 'enter-in-paste' → **忽略**（防止误触发发送）
 *
 *  工作原理：
 *    当用户粘贴多行内容时，stdin 可能分多个 chunk 到达。
 *    如果不处理，粘贴内容中的 \n 会被解析为 Enter 键，
 *    导致只有最后一个换行之前的内容被保留，或者直接触发了发送。
 * ============================================================
 */
import { useCallback, useRef, useState } from 'react';
// 粘贴检测阈值：超过此长度视为粘贴输入
const PASTE_THRESHOLD = 20;
// 多 Chunk 等待超时：100ms 内收到的内容视为同一批粘贴
const PASTE_TIMEOUT_MS = 100;
/**
 * 粘贴检测 Hook（v0.3 最终版）
 *
 * @example
 * ```tsx
 * const { handleInput } = usePasteHandler({
 *   onPasteComplete: (text) => {
 *     buf.insert(text);
 *     forceRefresh();
 *   },
 *   multiline: true,
 * });
 *
 * useInput((input, key) => {
 *   const result = handleInput(input, key);
 *   if (result === 'paste') return;           // 粘贴已处理
 *   if (result === 'enter-in-paste') return;  // 粘贴中的 Enter 忽略
 *   if (result === 'enter-newline') {         // Alt+Enter → 换行
 *     buf.insert('\n');
 *     forceRefresh();
 *     return;
 *   }
 *   // result === 'continue': 正常处理
 *   // 包括：Enter 发送、Ctrl+Enter 发送、普通字符输入等
 * });
 * ```
 */
export function usePasteHandler({ onPasteComplete, multiline = false, }) {
    const [isPasting, setIsPasting] = useState(false);
    const pasteStateRef = useRef({
        chunks: [],
        timeoutId: null,
    });
    /**
     * 刷新 UI 的引用（避免闭包问题）
     */
    const onPasteCompleteRef = useRef(onPasteComplete);
    onPasteCompleteRef.current = onPasteComplete;
    /**
     * 刷新 isPasting 状态的引用
     */
    const setIsPastingRef = useRef(setIsPasting);
    setIsPastingRef.current = setIsPasting;
    /**
     * 将收集的 chunks 合并并触发回调
     */
    const flushPaste = useCallback(() => {
        const { chunks } = pasteStateRef.current;
        if (chunks.length === 0)
            return;
        // 合并所有 chunks
        const rawText = chunks.join('');
        // 清理文本：
        // 1. \r\n → \n（Windows 行尾）
        // 2. 连续的 \n 压缩为最多两个（保持段落分隔）
        const cleanedText = rawText
            .replace(/\r\n/g, '\n')
            .replace(/\r/g, '\n')
            .replace(/\n{3,}/g, '\n\n');
        // 清除状态
        pasteStateRef.current = { chunks: [], timeoutId: null };
        setIsPastingRef.current(false);
        // 触发回调
        onPasteCompleteRef.current(cleanedText);
    }, []);
    /**
     * 处理输入（v0.3：Enter 始终发送，Alt+Enter 换行，粘贴期间拦截）
     */
    const handleInput = useCallback((input, key) => {
        // ---- 1. 粘贴期间的任何 Enter 键：全部拦截 ----
        // 这是最关键的防御！防止多行粘贴内容中的 \n 触发发送
        if (isPasting && key.return) {
            return 'enter-in-paste';
        }
        // ---- 2. Alt+Enter（Mac: Option+Enter）：插入换行符（用于编辑时手动换行）----
        // multiline=false 时不识别 Alt+Enter，让它走到下面的普通 Enter 分支（提交）
        if (multiline && key.return && key.meta && !key.ctrl) {
            return 'enter-newline';
        }
        // ---- 3. Enter（包括 Ctrl+Enter）：始终返回 continue → 让调用方处理为发送 ----
        // 不管是单行还是多行内容，Enter 的默认行为都是发送
        // 只有 Alt+Enter 才是换行
        if (key.return) {
            return 'continue'; // 调用方会执行 onSubmit()
        }
        // ---- 4. 检测是否为粘贴输入 ----
        const isLongInput = input.length > PASTE_THRESHOLD;
        if (isLongInput || isPasting) {
            // 进入或继续粘贴状态
            setIsPasting(true);
            // 清除之前的超时
            if (pasteStateRef.current.timeoutId) {
                clearTimeout(pasteStateRef.current.timeoutId);
            }
            // 收集这个 chunk
            pasteStateRef.current.chunks.push(input);
            // 设置新的超时，超时后 flush
            pasteStateRef.current.timeoutId = setTimeout(() => {
                flushPaste();
            }, PASTE_TIMEOUT_MS);
            return 'paste';
        }
        // ---- 5. 普通输入，继续处理 ----
        return 'continue';
    }, [isPasting, multiline, flushPaste]);
    return {
        handleInput,
        isPasting,
    };
}
