import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import React__default, { useMemo } from 'react';
import { cn } from '../../../utils/cn.js';
import { formatTimestamp } from '../../../utils/dateUtils.js';
import { messageTheme } from './Message.theme.js';
import { Avatar } from '../Avatar/Avatar.js';
import { Button } from '../Button/Button.js';
import { motion } from 'motion/react';
import { DocumentDuplicateIcon, ArrowPathIcon } from '@heroicons/react/24/outline';
import { MessageContext } from './MessageContext.js';
import { MessageAvatar } from './MessageAvatar.js';
import { MessageBody } from './MessageBody.js';
import { MessageActions } from './MessageActions.js';
import { MessageTimestamp } from './MessageTimestamp.js';
import { MessageList } from './MessageList.js';
import { TypeWriter } from './TypeWriter.js';
import { MessageStatusIndicator } from './MessageStatusIndicator.js';
import { MessageSenderName } from './MessageSenderName.js';
import { MessageFile } from './MessageFile.js';
import { MessageImage } from './MessageImage.js';
import { MessageAudio } from './MessageAudio.js';
import { MessageLink } from './MessageLink.js';
import { MessageReply } from './MessageReply.js';
import { MessageReactions } from './MessageReactions.js';
import { MessageDateDivider } from './MessageDateDivider.js';

const MessageFooter = ({ isStreaming, streamingIndicator, showTimestamp, timestamp, actions, timestampStyle, streamingIndicatorStyle, actionsContainerStyle, variant, }) => {
    if (isStreaming) {
        return (jsx("div", { className: cn("flex flex-row items-center gap-3 mt-1", variant === "receiver" ? "ml-2" : "mr-3"), children: jsx("div", { className: cn(timestampStyle, streamingIndicatorStyle), children: streamingIndicator || (jsxs(Fragment, { children: [jsx("span", { children: "Typing" }), jsx(motion.span, { animate: { opacity: [0.4, 1, 0.4] }, transition: {
                                duration: 1.5,
                                repeat: Infinity,
                                ease: "easeInOut",
                            }, children: "\u2022\u2022\u2022" })] })) }) }));
    }
    // For system variant, only show timestamp (no actions)
    if (variant === "system") {
        return showTimestamp && timestamp ? (jsx("div", { className: timestampStyle, children: jsx("time", { dateTime: typeof timestamp === "string" ? timestamp : timestamp.toISOString(), className: "select-none", children: formatTimestamp(timestamp) }) })) : null;
    }
    // For sender/receiver variants, show timestamp and actions in a row
    return (jsxs("div", { className: cn(`flex flex-row items-center gap-3 mt-3`, variant === "receiver" ? "-ml-0" : "mr-3"), children: [showTimestamp && timestamp && (jsx("div", { className: timestampStyle, children: jsx("time", { dateTime: typeof timestamp === "string"
                        ? timestamp
                        : timestamp.toISOString(), className: "select-none", children: formatTimestamp(timestamp) }) })), actions && jsx("div", { className: cn(actionsContainerStyle), children: actions })] }));
};
/**
 * Renders attachment sub-components based on attachment type
 */
const AttachmentsList = ({ attachments, containerClassName }) => {
    return (jsx("div", { className: cn(messageTheme.attachmentContainerStyle, containerClassName), children: attachments.map((attachment, index) => {
            switch (attachment.type) {
                case "file":
                    return (jsx(MessageFile, { name: attachment.name, url: attachment.url, size: attachment.size }, index));
                case "image":
                    return (jsx(MessageImage, { src: attachment.url, thumbnailUrl: attachment.thumbnailUrl, name: attachment.name, size: attachment.size }, index));
                case "audio":
                    return (jsx(MessageAudio, { name: attachment.name, duration: attachment.duration }, index));
                case "link":
                    return (jsx(MessageLink, { url: attachment.url, thumbnailUrl: attachment.thumbnailUrl, title: attachment.name, description: attachment.description, domain: attachment.domain }, index));
                default:
                    return null;
            }
        }) }));
};
const MessageRoot = React__default.forwardRef(({ role, variant: variantProp, content, timestamp, avatar, showTimestamp = false, isStreaming = false, streamingIndicator, typingSpeed = 100, actions, onCopy, onRegenerate, showActions, status, readAt, onRetry, attachments, reactions, onReactionClick, replyTo, sender, isGrouped, className, theme: customTheme = {}, children, ...props }, ref) => {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    // Determine the variant: role takes precedence over variant prop
    let variant;
    if (role) {
        // Map role to variant
        variant =
            role === "user"
                ? "sender"
                : role === "assistant"
                    ? "receiver"
                    : "system";
    }
    else {
        // Use variant prop or default
        variant = variantProp || "receiver";
    }
    // Detect if using compound API (has children)
    const isCompoundAPI = !!children;
    // Context value for compound components
    const contextValue = useMemo(() => ({
        role,
        variant,
        isStreaming,
        typingSpeed,
        status,
        isGrouped,
    }), [role, variant, isStreaming, typingSpeed, status, isGrouped]);
    const messageContent = content;
    // Determine if we should show default actions
    const shouldShowDefaultActions = showActions !== false &&
        (variant === "receiver" || role === "assistant") &&
        (onCopy || onRegenerate);
    if (isCompoundAPI) {
        // Compound API - Render with context
        const variantTheme = messageTheme.variants[variant];
        // Build container style
        const containerStyle = cn(messageTheme.containerBaseStyle, variantTheme.containerModifier, customTheme.containerBaseStyle, (_b = (_a = customTheme.variants) === null || _a === void 0 ? void 0 : _a[variant]) === null || _b === void 0 ? void 0 : _b.containerModifier, 
        // Backward compatibility
        variant === "sender" && customTheme.senderContainerStyle, variant === "receiver" && customTheme.receiverContainerStyle, variant === "system" && customTheme.systemContainerStyle);
        return (jsx(MessageContext.Provider, { value: contextValue, children: jsx("div", { ref: ref, className: cn("w-full max-w-full group", className), "data-variant": variant, "data-role": role, ...props, children: jsx("div", { className: containerStyle, children: children }) }) }));
    }
    // Props API - Render inline
    // Get variant-specific theme
    const variantTheme = messageTheme.variants[variant];
    // Build container styles
    const containerStyle = cn(messageTheme.containerBaseStyle, variantTheme.containerModifier, customTheme.containerBaseStyle, (_d = (_c = customTheme.variants) === null || _c === void 0 ? void 0 : _c[variant]) === null || _d === void 0 ? void 0 : _d.containerModifier, 
    // Backward compatibility
    variant === "sender" && customTheme.senderContainerStyle, variant === "receiver" && customTheme.receiverContainerStyle, variant === "system" && customTheme.systemContainerStyle);
    // Build bubble styles
    const bubbleStyle = cn(messageTheme.bubbleBaseStyle, variantTheme.bubbleStyle, customTheme.bubbleBaseStyle, (_f = (_e = customTheme.variants) === null || _e === void 0 ? void 0 : _e[variant]) === null || _f === void 0 ? void 0 : _f.bubbleStyle, 
    // Backward compatibility
    variant === "sender" && customTheme.senderBubbleStyle, variant === "receiver" && customTheme.receiverBubbleStyle, variant === "system" && customTheme.systemBubbleStyle);
    // Build timestamp styles
    const timestampStyle = cn(messageTheme.timestampStyle, variantTheme.timestampModifier, customTheme.timestampStyle, (_h = (_g = customTheme.variants) === null || _g === void 0 ? void 0 : _g[variant]) === null || _h === void 0 ? void 0 : _h.timestampModifier, 
    // Backward compatibility
    variant === "sender" && customTheme.senderTimestampStyle, variant === "receiver" && customTheme.receiverTimestampStyle, variant === "system" && customTheme.systemTimestampStyle);
    // Build default action buttons if needed
    const defaultActionButtons = shouldShowDefaultActions ? (jsxs("div", { className: cn(messageTheme.actionsContainerStyle, customTheme.actionsContainerStyle), children: [onCopy && (jsx(Button, { variant: "link", color: "neutral", size: "sm", onClick: onCopy, "aria-label": "Copy message", className: "opacity-40 hover:opacity-100", children: jsx(DocumentDuplicateIcon, { className: "size-4" }) })), onRegenerate && (jsx(Button, { variant: "link", color: "neutral", size: "sm", onClick: onRegenerate, "aria-label": "Regenerate response", className: "opacity-40 hover:opacity-100", children: jsx(ArrowPathIcon, { className: "size-4" }) }))] })) : undefined;
    // Use custom actions if provided, otherwise use default actions
    const finalActions = actions !== null && actions !== void 0 ? actions : defaultActionButtons;
    // Use TypeWriter for streaming receiver/assistant messages with string content (props API)
    const shouldAnimate = (variant === "receiver" || role === "assistant") &&
        isStreaming &&
        typeof messageContent === "string";
    const renderedContent = shouldAnimate ? (jsx(TypeWriter, { text: messageContent, speed: typingSpeed, enabled: true, className: "break-words" })) : (messageContent);
    // System messages render differently (centered, no avatar)
    if (variant === "system") {
        return (jsx("div", { ref: ref, className: cn("w-full max-w-full", className), "data-variant": "system", "data-role": role, ...props, children: jsxs("div", { className: containerStyle, children: [jsx("div", { className: bubbleStyle, children: typeof renderedContent === "string" ? (jsx("p", { className: "text-base", children: renderedContent })) : (renderedContent) }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: undefined, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: undefined, variant: "system" })] }) }));
    }
    const showAvatar = avatar && !isGrouped;
    const showSenderName = (sender === null || sender === void 0 ? void 0 : sender.name) && variant === "receiver" && !isGrouped;
    return (jsxs("div", { ref: ref, className: cn("w-full max-w-full group", className), "data-variant": variant, "data-role": role, ...props, children: [jsxs("div", { className: containerStyle, children: [showAvatar ? (jsx("div", { className: "flex-shrink-0", children: jsx(Avatar, { src: avatar.src, name: avatar.name, fallback: avatar.fallback, size: "xs" }) })) : isGrouped && avatar ? (jsx("div", { className: "flex-shrink-0 size-8" })) : null, jsxs("div", { className: cn("flex flex-col", variant === "sender" ? "items-end" : "items-start"), children: [showSenderName && jsx(MessageSenderName, { name: sender.name }), jsxs("div", { className: bubbleStyle, children: [replyTo && (jsx(MessageReply, { name: replyTo.name, content: replyTo.content, avatar: replyTo.avatar })), typeof renderedContent === "string" ? (jsx("p", { className: "break-words", children: renderedContent })) : (renderedContent), attachments && attachments.length > 0 && (jsx(AttachmentsList, { attachments: attachments, containerClassName: customTheme.attachmentContainerStyle }))] }), jsx(MessageFooter, { isStreaming: isStreaming, streamingIndicator: streamingIndicator, showTimestamp: showTimestamp, timestamp: timestamp, actions: finalActions, timestampStyle: timestampStyle, streamingIndicatorStyle: cn(messageTheme.streamingIndicatorStyle, customTheme.streamingIndicatorStyle), actionsContainerStyle: cn(messageTheme.actionsContainerStyle, customTheme.actionsContainerStyle), variant: variant }), status && variant === "sender" && (jsx(MessageStatusIndicator, { status: status, readAt: readAt, onRetry: onRetry, className: cn(variant === "sender" ? "self-end mr-1" : "self-start ml-1", customTheme.statusStyle) }))] })] }), reactions && reactions.length > 0 && (jsx("div", { className: cn("mt-0.5", avatar && !isGrouped ? "ml-11" : "", variant === "sender" ? "flex justify-end mr-1" : ""), children: jsx(MessageReactions, { reactions: reactions, onReactionClick: onReactionClick, className: customTheme.reactionsContainerStyle }) }))] }));
});
MessageRoot.displayName = "Message";
// Attach compound components
const Message = Object.assign(MessageRoot, {
    Avatar: MessageAvatar,
    Body: MessageBody,
    Actions: MessageActions,
    Timestamp: MessageTimestamp,
    List: MessageList,
    Status: MessageStatusIndicator,
    SenderName: MessageSenderName,
    File: MessageFile,
    Image: MessageImage,
    Audio: MessageAudio,
    Link: MessageLink,
    Reply: MessageReply,
    Reactions: MessageReactions,
    DateDivider: MessageDateDivider,
});

export { Message };
