import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import React__default, { useState, useRef, useId, useEffect, useCallback } from 'react';
import { AnimatePresence, motion } from 'motion/react';
import { cn } from '../../../utils/cn.js';
import { CloudArrowUpIcon, MicrophoneIcon, PaperClipIcon, LinkIcon, DocumentIcon, XMarkIcon, PlusIcon, AdjustmentsHorizontalIcon, ChevronDownIcon, ArrowRightIcon } from '@heroicons/react/24/outline';
import { StopIcon } from '@heroicons/react/24/solid';
import { promptInputTheme } from './PromptInput.theme.js';
import { VoiceRecorder } from './VoiceRecorder.js';
import { dropzoneContainerVariants, dropzoneChildVariants, dropzoneActionIconVariants, textareaSwapVariants, iconSwapVariants } from './PromptInput.animations.js';
import { Textarea } from '../../forms/Textarea/Textarea.js';
import '../../forms/Textarea/Textarea.theme.js';
import { Dropdown } from '../../core/Dropdown/Dropdown.js';
import '../../core/Dropdown/DropdownTrigger.js';
import '../../core/Dropdown/DropdownMenu.js';
import '../../core/Dropdown/DropdownItem.js';
import '../../core/Dropdown/DropdownSection.js';
import '../../core/Dropdown/DropdownSeparator.js';
import '../../core/Dropdown/Dropdown.theme.js';
import { Button } from '../../core/Button/Button.js';

/**
 * Default model options for the model selector
 */
const DEFAULT_MODELS = [
    { key: "sonnet", label: "Claude 3.5 Sonnet" },
    { key: "gpt", label: "GPT-5 Turbo" },
    { key: "gemini", label: "Gemini 2.5" },
];
/**
 * AI prompt input component with integrated controls for model selection,
 * attachments, voice input, and settings.
 *
 * Supports both controlled and uncontrolled patterns for maximum flexibility.
 *
 * @example Uncontrolled usage
 * ```tsx
 * <PromptInput onSubmit={(text, model) => handlePrompt(text, model)} />
 * ```
 *
 * @example Controlled usage
 * ```tsx
 * <PromptInput
 *   value={prompt}
 *   onChange={setPrompt}
 *   selectedModel={model}
 *   onModelChange={setModel}
 * />
 * ```
 */
const PromptInput = React__default.forwardRef(({ 
// Value control
value, defaultValue = "", onChange, 
// Textarea props
placeholder = "How may I assist you today?", maxLength, minHeight: minHeightProp, maxHeight = "120px", rows, 
// State
state = "default", disabled = false, helperText, showCharCount = false, 
// Model selection
selectedModel: controlledModel, defaultSelectedModel, models = DEFAULT_MODELS, onModelChange, 
// Event handlers
onSubmit, onAttachmentClick, onVoiceClick, onSettingsClick, onKeyDown, 
// Stop generation
onStop, 
// Voice recording
enableVoiceRecording = false, onRecordingComplete, onRecordingCancel, maxRecordingDuration = 120, 
// Dropzone
enableDropzone = true, dropzoneText = "Drop files here to add to chat", dropzoneTitle, dropzoneSubtitle, 
// Multimodal attachments
attachments: controlledAttachments, onAttachmentsChange, acceptedFileTypes = ["image/*", "application/pdf"], maxFileSize = 10 * 1024 * 1024, maxAttachments = 10, compressImages = true, maxImageDimension = 1024, imageQuality = 0.8, onAttachmentError, 
// Button visibility
showAttachmentButton = true, showVoiceButton = true, showSettingsButton = true, showModelSelector = true, 
// Submit button
submitButtonLabel = "Submit prompt", submitButtonIcon = (jsx(ArrowRightIcon, { className: "size-4", strokeWidth: 2.5 })), submitShortcut, 
// Variant
variant = "default", 
// Styling
className, textareaClassName, footerClassName, theme = {}, 
// Accessibility
"aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, id: propId, ...props }, ref) => {
    var _a, _b;
    // Derive minHeight: simple variant defaults to a compact single-line height
    const minHeight = minHeightProp !== null && minHeightProp !== void 0 ? minHeightProp : (variant === "simple" ? "32px" : "48px");
    // ========== State Management ==========
    // Internal state for uncontrolled mode
    const [internalValue, setInternalValue] = useState(defaultValue);
    const [internalAttachments, setInternalAttachments] = useState([]);
    const [internalModel, setInternalModel] = useState([
        defaultSelectedModel || ((_a = models[0]) === null || _a === void 0 ? void 0 : _a.key) || "",
    ]);
    const [isRecording, setIsRecording] = useState(false);
    // Ref for textarea element
    const internalTextareaRef = useRef(null);
    const textareaRef = ref || internalTextareaRef;
    const fileInputRef = useRef(null);
    const dragCounterRef = useRef(0);
    const [isDragOver, setIsDragOver] = useState(false);
    const uniqueId = useId();
    // Determine if component is controlled
    const isControlled = value !== undefined;
    const isModelControlled = controlledModel !== undefined;
    const isAttachmentsControlled = controlledAttachments !== undefined;
    // Get current value
    const currentValue = isControlled ? value : internalValue;
    const currentModel = isModelControlled ? controlledModel : internalModel[0];
    const currentAttachments = isAttachmentsControlled
        ? controlledAttachments
        : internalAttachments;
    // Generate ID for accessibility
    const id = propId || uniqueId;
    const helperTextId = helperText ? `${id}-helper` : undefined;
    // ========== Derived State ==========
    const isDisabled = state === "disabled" || disabled;
    const isInvalid = state === "invalid";
    const isLoading = state === "loading";
    const showStopButton = isLoading && onStop !== undefined;
    const canSubmit = (currentValue.trim().length > 0 || currentAttachments.length > 0) &&
        !isDisabled;
    // Model key to display name mapping
    const modelMap = models.reduce((acc, model) => {
        acc[model.key] = model.label;
        return acc;
    }, {});
    // ========== Development Warnings ==========
    useEffect(() => {
        if (process.env.NODE_ENV !== "production") {
            if (isControlled && !onChange) {
                // eslint-disable-next-line no-console
                console.warn("[PromptInput] Component is controlled (value prop provided) but missing onChange handler. The input will be read-only.");
            }
            if (!onSubmit) {
                // eslint-disable-next-line no-console
                console.warn("[PromptInput] No onSubmit handler provided. Submit button will have no effect.");
            }
        }
    }, [isControlled, onChange, onSubmit]);
    // ========== Event Handlers ==========
    /**
     * Handle textarea value change
     */
    const handleChange = useCallback((e) => {
        const newValue = e.target.value;
        // Enforce maxLength if provided
        if (maxLength && newValue.length > maxLength) {
            return;
        }
        // Update internal state if uncontrolled
        if (!isControlled) {
            setInternalValue(newValue);
        }
        // Call user's onChange handler
        onChange === null || onChange === void 0 ? void 0 : onChange(newValue, e);
    }, [isControlled, maxLength, onChange]);
    /**
     * Handle model selection change
     */
    const handleModelChange = useCallback((keys) => {
        if (keys === "all")
            return;
        const newModel = String(keys[0]);
        // Update internal state if uncontrolled
        if (!isModelControlled) {
            setInternalModel([newModel]);
        }
        // Call user's handler
        onModelChange === null || onModelChange === void 0 ? void 0 : onModelChange(newModel);
    }, [isModelControlled, onModelChange]);
    // ========== Voice Recording Handlers ==========
    /**
     * Handle voice button click — either start inline recording or call onVoiceClick
     */
    const handleVoiceClick = useCallback(() => {
        if (enableVoiceRecording) {
            setIsRecording(true);
        }
        else {
            onVoiceClick === null || onVoiceClick === void 0 ? void 0 : onVoiceClick();
        }
    }, [enableVoiceRecording, onVoiceClick]);
    /**
     * Handle recording complete
     */
    const handleRecordingComplete = useCallback((audioBlob) => {
        setIsRecording(false);
        onRecordingComplete === null || onRecordingComplete === void 0 ? void 0 : onRecordingComplete(audioBlob);
    }, [onRecordingComplete]);
    /**
     * Handle recording cancel
     */
    const handleRecordingCancel = useCallback(() => {
        setIsRecording(false);
        onRecordingCancel === null || onRecordingCancel === void 0 ? void 0 : onRecordingCancel();
    }, [onRecordingCancel]);
    // ========== Multimodal Handlers ==========
    /**
     * Validate file type
     */
    const isValidFileType = useCallback((file) => {
        if (acceptedFileTypes.length === 0)
            return true;
        return acceptedFileTypes.some((type) => {
            if (type.includes("/*")) {
                const [category] = type.split("/");
                return file.type.startsWith(`${category}/`);
            }
            if (type.startsWith(".")) {
                return file.name.toLowerCase().endsWith(type.toLowerCase());
            }
            return file.type === type;
        });
    }, [acceptedFileTypes]);
    /**
     * Compress image using canvas
     */
    const compressImage = useCallback(async (file) => {
        if (!compressImages || !file.type.startsWith("image/")) {
            return file;
        }
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.onload = () => {
                let { width, height } = img;
                if (width > maxImageDimension || height > maxImageDimension) {
                    if (width > height) {
                        height = (height / width) * maxImageDimension;
                        width = maxImageDimension;
                    }
                    else {
                        width = (width / height) * maxImageDimension;
                        height = maxImageDimension;
                    }
                }
                const canvas = document.createElement("canvas");
                canvas.width = width;
                canvas.height = height;
                const ctx = canvas.getContext("2d");
                if (!ctx) {
                    reject(new Error("Failed to get canvas context"));
                    return;
                }
                ctx.drawImage(img, 0, 0, width, height);
                canvas.toBlob((blob) => {
                    if (blob) {
                        resolve(new File([blob], file.name, {
                            type: file.type,
                            lastModified: Date.now(),
                        }));
                    }
                    else {
                        reject(new Error("Failed to compress"));
                    }
                }, file.type, imageQuality);
            };
            img.onerror = () => reject(new Error("Failed to load image"));
            img.src = URL.createObjectURL(file);
        });
    }, [compressImages, maxImageDimension, imageQuality]);
    /**
     * Update attachments (handles controlled/uncontrolled)
     */
    const updateAttachments = useCallback((newAttachments) => {
        if (!isAttachmentsControlled) {
            setInternalAttachments(newAttachments);
        }
        onAttachmentsChange === null || onAttachmentsChange === void 0 ? void 0 : onAttachmentsChange(newAttachments);
    }, [isAttachmentsControlled, onAttachmentsChange]);
    /**
     * Process and add files
     */
    const processFiles = useCallback(async (files) => {
        const fileArray = Array.from(files);
        for (const file of fileArray) {
            if (currentAttachments.length >= maxAttachments) {
                onAttachmentError === null || onAttachmentError === void 0 ? void 0 : onAttachmentError({
                    type: "too-many-attachments",
                    message: `Maximum ${maxAttachments} attachments allowed`,
                });
                return;
            }
            if (!isValidFileType(file)) {
                onAttachmentError === null || onAttachmentError === void 0 ? void 0 : onAttachmentError({
                    type: "file-invalid-type",
                    message: `File type not accepted: ${file.name}`,
                    file,
                });
                continue;
            }
            if (file.size > maxFileSize) {
                const maxSizeMB = (maxFileSize / (1024 * 1024)).toFixed(1);
                onAttachmentError === null || onAttachmentError === void 0 ? void 0 : onAttachmentError({
                    type: "file-too-large",
                    message: `File too large: ${file.name} (max ${maxSizeMB}MB)`,
                    file,
                });
                continue;
            }
            const isImage = file.type.startsWith("image/");
            const attachmentId = `${uniqueId}-${Date.now()}-${Math.random()}`;
            const newAttachment = {
                id: attachmentId,
                file,
                type: isImage ? "image" : "file",
                isCompressing: isImage && compressImages,
            };
            const updated = [...currentAttachments, newAttachment];
            updateAttachments(updated);
            if (isImage && compressImages) {
                try {
                    const compressedFile = await compressImage(file);
                    const previewUrl = URL.createObjectURL(compressedFile);
                    updateAttachments(updated.map((a) => a.id === attachmentId
                        ? {
                            ...a,
                            file: compressedFile,
                            previewUrl,
                            isCompressing: false,
                        }
                        : a));
                }
                catch (_a) {
                    const previewUrl = URL.createObjectURL(file);
                    updateAttachments(updated.map((a) => a.id === attachmentId
                        ? { ...a, previewUrl, isCompressing: false }
                        : a));
                }
            }
            else if (isImage) {
                const previewUrl = URL.createObjectURL(file);
                updateAttachments(updated.map((a) => a.id === attachmentId ? { ...a, previewUrl } : a));
            }
        }
    }, [
        currentAttachments,
        maxAttachments,
        maxFileSize,
        isValidFileType,
        compressImages,
        compressImage,
        onAttachmentError,
        uniqueId,
        updateAttachments,
    ]);
    /**
     * Handle paste for images
     */
    const handlePaste = useCallback((e) => {
        var _a;
        const items = (_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.items;
        if (!items)
            return;
        const files = [];
        for (const item of Array.from(items)) {
            if (item.kind === "file") {
                const file = item.getAsFile();
                if (file)
                    files.push(file);
            }
        }
        if (files.length > 0) {
            e.preventDefault();
            processFiles(files);
        }
    }, [processFiles]);
    // ========== Drag & Drop Handlers ==========
    const handleDragEnter = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        dragCounterRef.current++;
        if (dragCounterRef.current === 1 && !isDisabled && enableDropzone) {
            setIsDragOver(true);
        }
    }, [isDisabled, enableDropzone]);
    const handleDragOver = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
    }, []);
    const handleDragLeave = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        dragCounterRef.current--;
        if (dragCounterRef.current === 0) {
            setIsDragOver(false);
        }
    }, []);
    const handleDrop = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        dragCounterRef.current = 0;
        setIsDragOver(false);
        if (!isDisabled && e.dataTransfer.files.length > 0) {
            processFiles(e.dataTransfer.files);
        }
    }, [isDisabled, processFiles]);
    /**
     * Remove attachment
     */
    const removeAttachment = useCallback((attachmentId) => {
        const attachment = currentAttachments.find((a) => a.id === attachmentId);
        if (attachment === null || attachment === void 0 ? void 0 : attachment.previewUrl) {
            URL.revokeObjectURL(attachment.previewUrl);
        }
        updateAttachments(currentAttachments.filter((a) => a.id !== attachmentId));
    }, [currentAttachments, updateAttachments]);
    /**
     * Handle submit action
     */
    const handleSubmit = useCallback(() => {
        const trimmedValue = currentValue.trim();
        if (!trimmedValue && currentAttachments.length === 0) {
            return;
        }
        if (isDisabled) {
            return;
        }
        // Call onSubmit with trimmed value and current model
        onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(trimmedValue, currentModel);
        // Clear input after submit if uncontrolled
        if (!isControlled) {
            setInternalValue("");
        }
        if (!isAttachmentsControlled) {
            currentAttachments.forEach((a) => {
                if (a.previewUrl)
                    URL.revokeObjectURL(a.previewUrl);
            });
            setInternalAttachments([]);
        }
    }, [
        currentValue,
        currentModel,
        currentAttachments,
        isDisabled,
        onSubmit,
        isControlled,
        isAttachmentsControlled,
    ]);
    /**
     * Handle keyboard shortcuts
     */
    const handleKeyDown = useCallback((e) => {
        var _a;
        // Cmd/Ctrl+Enter to submit
        if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
            e.preventDefault();
            handleSubmit();
            return;
        }
        // Escape to clear (only in uncontrolled mode)
        if (e.key === "Escape" && !isControlled) {
            setInternalValue("");
            (_a = textareaRef.current) === null || _a === void 0 ? void 0 : _a.blur();
            return;
        }
        // Call user's onKeyDown handler
        onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
    }, [handleSubmit, isControlled, onKeyDown, textareaRef]);
    // ========== Auto-resize Logic ==========
    /**
     * Auto-resize textarea based on content
     */
    useEffect(() => {
        if (textareaRef.current) {
            const minH = parseInt(minHeight, 10);
            const maxH = parseInt(maxHeight, 10);
            // Reset height to minimum first
            textareaRef.current.style.height = minHeight;
            // Calculate new height based on scroll height
            const scrollH = textareaRef.current.scrollHeight;
            const newHeight = Math.min(Math.max(scrollH, minH), maxH);
            // Apply new height
            textareaRef.current.style.height = `${newHeight}px`;
        }
    }, [currentValue, minHeight, maxHeight, textareaRef]);
    // ========== Theme Merging ==========
    const mergedTheme = {
        baseStyle: theme.baseStyle || promptInputTheme.baseStyle,
        textareaStyle: theme.textareaStyle || promptInputTheme.textareaStyle,
        footerStyle: theme.footerStyle || promptInputTheme.footerStyle,
        actionsStyle: theme.actionsStyle || promptInputTheme.actionsStyle,
        submitButtonStyle: theme.submitButtonStyle || promptInputTheme.submitButtonStyle,
        dropzoneStyle: theme.dropzoneStyle || promptInputTheme.dropzoneStyle,
        dropzoneTitleStyle: theme.dropzoneTitleStyle || promptInputTheme.dropzoneTitleStyle,
        dropzoneSubtitleStyle: theme.dropzoneSubtitleStyle || promptInputTheme.dropzoneSubtitleStyle,
        dropzoneActionsStyle: theme.dropzoneActionsStyle || promptInputTheme.dropzoneActionsStyle,
        voiceRecorderStyle: theme.voiceRecorderStyle || promptInputTheme.voiceRecorderStyle,
        stateStyle: ((_b = theme.states) === null || _b === void 0 ? void 0 : _b[state]) || promptInputTheme.states[state],
    };
    // ========== Character Count ==========
    const displayHelperText = showCharCount
        ? `${currentValue.length}${maxLength ? `/${maxLength}` : ""} characters${helperText ? ` • ${helperText}` : ""}`
        : helperText;
    // ========== Dropzone Helpers ==========
    const resolvedDropzoneTitle = dropzoneTitle || dropzoneText;
    /**
     * Handle "browse" click within the dropzone overlay
     */
    const handleDropzoneBrowse = useCallback(() => {
        setIsDragOver(false);
        dragCounterRef.current = 0;
        if (fileInputRef.current) {
            fileInputRef.current.accept = acceptedFileTypes.join(",");
            fileInputRef.current.click();
        }
    }, [acceptedFileTypes]);
    // ========== Submit/Stop Button Renderer ==========
    /**
     * Renders the submit or stop button with animated icon swap.
     * Used by both default and simple variants.
     */
    const renderSubmitButton = (buttonSize, buttonVariant, buttonColor, extraClassName) => {
        if (showStopButton) {
            return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: "danger", onClick: onStop, "aria-label": "Stop generation", title: "Stop generation", showReflection: false, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: jsx(StopIcon, { className: "size-4" }) }, "stop") }) }));
        }
        return (jsx(Button, { iconOnly: true, className: cn(mergedTheme.submitButtonStyle, extraClassName), size: buttonSize, variant: buttonVariant, color: buttonColor, onClick: handleSubmit, disabled: !canSubmit, state: isLoading ? "loading" : "default", "aria-label": submitButtonLabel, title: submitShortcut ? `Submit (${submitShortcut})` : undefined, showReflection: buttonVariant === "filled" ? false : undefined, children: jsx(AnimatePresence, { mode: "wait", initial: false, children: jsx(motion.span, { variants: iconSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex items-center justify-center", children: submitButtonIcon }, "submit") }) }));
    };
    // ========== Render ==========
    return (jsxs("div", { className: cn("w-full mx-auto", className), ...props, children: [jsx("input", { ref: fileInputRef, type: "file", accept: acceptedFileTypes.join(","), multiple: true, onChange: (e) => {
                    if (e.target.files)
                        processFiles(e.target.files);
                    e.target.value = "";
                }, className: "sr-only", "aria-label": "Attach files" }), jsxs("div", { className: cn("relative", mergedTheme.baseStyle, mergedTheme.stateStyle, variant === "simple" ? "p-3 rounded-full pl-5" : ""), onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx(AnimatePresence, { children: isDragOver && enableDropzone && (jsxs(motion.div, { variants: dropzoneContainerVariants, initial: "initial", animate: "animate", exit: "exit", className: mergedTheme.dropzoneStyle, children: [jsx(motion.div, { variants: dropzoneChildVariants, children: jsx(CloudArrowUpIcon, { className: "size-8 text-[var(--color-primary)] mx-auto" }) }), jsx(motion.p, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneTitleStyle, children: dropzoneTitle ? (
                                    // Parse **browse** as clickable button
                                    jsx(Fragment, { children: resolvedDropzoneTitle
                                            .split(/\*\*(.*?)\*\*/)
                                            .map((part, i) => i % 2 === 1 ? (jsx("button", { type: "button", onClick: handleDropzoneBrowse, className: "font-bold underline underline-offset-2 cursor-pointer hover:opacity-80", children: part }, i)) : (jsx("span", { children: part }, i))) })) : (resolvedDropzoneTitle) }), dropzoneSubtitle && (jsx(motion.p, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneSubtitleStyle, children: dropzoneSubtitle })), dropzoneTitle && (jsx(motion.div, { variants: dropzoneChildVariants, className: mergedTheme.dropzoneActionsStyle, children: [
                                        CloudArrowUpIcon,
                                        MicrophoneIcon,
                                        PaperClipIcon,
                                        LinkIcon,
                                    ].map((Icon, i) => (jsx(motion.div, { variants: dropzoneActionIconVariants, className: "size-8 rounded-full bg-white/30 dark:bg-white/10 flex items-center justify-center", children: jsx(Icon, { className: "size-4 text-[var(--color-primary)]" }) }, i))) }))] })) }), currentAttachments.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 py-2 px-1", children: currentAttachments.map((attachment) => {
                            var _a;
                            return (jsxs("div", { className: "relative group rounded-lg border border-[var(--color-border)] bg-white", children: [attachment.type === "image" ? (attachment.isCompressing ? (jsx("div", { className: "size-12 flex items-center justify-center bg-gray-100 rounded-lg", children: jsx("div", { className: "w-4 h-4 border-2 border-gray-300 border-t-[var(--color-primary)] rounded-full animate-spin" }) })) : (jsx("img", { src: attachment.previewUrl, alt: attachment.file.name, className: "size-12 object-cover rounded-lg" }))) : (jsxs("div", { className: "size-12 flex flex-col items-center justify-center text-center p-1 rounded-lg", children: [jsx(DocumentIcon, { className: "w-5 h-5 text-[var(--color-text-muted)]" }), jsx("span", { className: "text-[10px] text-[var(--color-text-secondary)] truncate w-full", children: (_a = attachment.file.name.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toUpperCase() })] })), jsx("button", { onClick: () => removeAttachment(attachment.id), className: "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-[var(--color-danger)] text-[var(--color-danger-contrast)] flex items-center justify-center opacity-0 translate-y-1 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 ease-in-out cursor-pointer shadow-md", "aria-label": `Remove ${attachment.file.name}`, children: jsx(XMarkIcon, { className: "size-3", strokeWidth: 3 }) })] }, attachment.id));
                        }) })), jsxs("div", { className: cn("flex gap-2", variant === "simple" ? "items-end" : "items-start"), children: [jsx(AnimatePresence, { mode: "wait", initial: false, children: isRecording && enableVoiceRecording ? (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex-1 min-w-0", children: jsx("p", { className: "text-center text-sm text-[var(--color-text-placeholder)]", children: placeholder }) }, "voice-recorder")) : (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: cn("flex-1 min-w-0", variant === "simple" && "flex items-end"), children: jsx(Textarea, { ref: textareaRef, id: id, unstyled: true, value: currentValue, onChange: handleChange, onKeyDown: handleKeyDown, onPaste: handlePaste, placeholder: placeholder, disabled: isDisabled, maxLength: maxLength, rows: rows, "aria-label": ariaLabel || "Prompt input", "aria-describedby": helperTextId, "aria-invalid": isInvalid, "aria-disabled": isDisabled, className: cn(mergedTheme.textareaStyle, variant === "simple" &&
                                            "!w-auto flex-1 min-w-0 justify-center", textareaClassName), style: {
                                            minHeight,
                                            maxHeight,
                                        } }) }, "textarea")) }), variant === "simple" &&
                                renderSubmitButton("md", "filled", "neutral", "shrink-0")] }), variant !== "simple" && (jsx("div", { className: cn(mergedTheme.footerStyle, footerClassName), children: jsx(AnimatePresence, { mode: "wait", initial: false, children: isRecording && enableVoiceRecording ? (jsx(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "w-full", children: jsx(VoiceRecorder, { onComplete: handleRecordingComplete, onCancel: handleRecordingCancel, maxDuration: maxRecordingDuration, className: mergedTheme.voiceRecorderStyle }) }, "recorder-controls")) : (jsxs(motion.div, { variants: textareaSwapVariants, initial: "initial", animate: "animate", exit: "exit", className: "flex justify-between items-end w-full", children: [jsxs("div", { className: mergedTheme.actionsStyle, children: [showAttachmentButton && (jsxs(Dropdown, { selectionMode: "none", children: [jsx(Dropdown.Trigger, { children: jsx(Button, { iconOnly: true, variant: "outline", color: "neutral", size: "sm", className: "rounded-full !border-0.5", "aria-label": "Add attachment", disabled: isDisabled, children: jsx(PlusIcon, { className: "size-4", strokeWidth: 2 }) }) }), jsxs(Dropdown.Menu, { children: [jsx(Dropdown.Item, { itemKey: "upload-image", onAction: () => {
                                                                    // Set accept to images only and trigger file input
                                                                    if (fileInputRef.current) {
                                                                        fileInputRef.current.accept = "image/*";
                                                                        fileInputRef.current.click();
                                                                    }
                                                                    onAttachmentClick === null || onAttachmentClick === void 0 ? void 0 : onAttachmentClick();
                                                                }, children: "Upload Image" }, "upload-image"), jsx(Dropdown.Item, { itemKey: "add-link", onAction: () => {
                                                                    // For now, just call the attachment callback
                                                                    // A link input modal could be added later
                                                                    onAttachmentClick === null || onAttachmentClick === void 0 ? void 0 : onAttachmentClick();
                                                                }, children: "Add Link" }, "add-link"), jsx(Dropdown.Item, { itemKey: "upload-pdf", onAction: () => {
                                                                    // Set accept to PDF and trigger file input
                                                                    if (fileInputRef.current) {
                                                                        fileInputRef.current.accept =
                                                                            "application/pdf,.pdf";
                                                                        fileInputRef.current.click();
                                                                    }
                                                                    onAttachmentClick === null || onAttachmentClick === void 0 ? void 0 : onAttachmentClick();
                                                                }, children: "Upload PDF" }, "upload-pdf")] })] })), showSettingsButton && (jsx(Button, { iconOnly: true, variant: "outline", color: "neutral", size: "sm", className: "rounded-full !border-0.5", onClick: onSettingsClick, "aria-label": "Open settings", disabled: isDisabled, children: jsx(AdjustmentsHorizontalIcon, { className: "size-4 text-[var(--color-text-muted)]", strokeWidth: 2 }) })), showVoiceButton && (jsxs(Button, { variant: "outline", color: "neutral", size: "sm", className: "bg-transparent rounded-full border-0 font-medium text-[var(--color-text-secondary)]", onClick: handleVoiceClick, "aria-label": "Voice input", disabled: isDisabled || isRecording, children: [jsx(MicrophoneIcon, { className: "size-4", strokeWidth: 2 }), " ", "Voice"] })), showModelSelector && (jsxs(Dropdown, { selectionMode: "single", selectedKeys: isModelControlled
                                                    ? [controlledModel]
                                                    : internalModel, onSelectionChange: handleModelChange, children: [jsx(Dropdown.Trigger, { children: jsxs(Button, { variant: "outline", color: "neutral", size: "sm", className: "bg-transparent rounded-full border-0 font-medium text-[var(--color-text-secondary)]", "aria-label": "Select AI model", disabled: isDisabled, children: [modelMap[currentModel] || "Select Model", jsx(ChevronDownIcon, { className: "size-3 opacity-80", strokeWidth: 2 })] }) }), jsx(Dropdown.Menu, { children: models.map((model) => (jsxs(Dropdown.Item, { itemKey: model.key, children: [model.icon && (jsx("span", { className: "mr-2", children: model.icon })), model.label] }, model.key))) })] }))] }), jsx("div", { children: renderSubmitButton("sm", "outline", "neutral") })] }, "footer-controls")) }) }))] }), displayHelperText && (jsx("div", { id: helperTextId, className: cn("mt-1 text-sm", isInvalid
                    ? "text-[var(--color-danger)]"
                    : "text-[var(--color-text-muted)]"), role: isInvalid ? "alert" : undefined, "aria-live": isInvalid ? "polite" : undefined, children: displayHelperText }))] }));
});
PromptInput.displayName = "PromptInput";

export { PromptInput };
