/*
 * Runtime Web – Unified Serverless Framework for Full-Stack TypeScript Applications
 * Documentation: https://runtimeweb.com/docs/getting-started
 *
 * @template: ai-chat
 */

/**
 * MessageBubble Component
 *
 * Renders a single message with role-based styling, avatar support,
 * timestamp display, markdown rendering, and reasoning section display.
 *
 * Features:
 * - Role-based styling (user/assistant) via BEM CSS classes
 * - Avatar display for assistant messages only
 * - Timestamp display for all messages
 * - Streaming cursor indicator when message.isStreaming is true
 * - Markdown rendering for assistant messages
 * - Reasoning section display (collapsible, small font)
 * - Isomorphic: works in both Lambda SSR and browser environments
 *
 * @requirements 2.1, 2.2, 2.3, 2.7, 2.8
 *
 * @example
 * <MessageBubble
 *   message={{ id: '1', role: 'assistant', content: 'Hello!', timestamp: '2025-01-01T12:00:00Z' }}
 *   showAvatar={true}
 * />
 */

import * as React from 'react';
import { useState, useMemo } from 'react';
import type { Message } from '../../types';
import { parseMessage } from '../../utils/parse-message';
import { MarkdownContent } from './MarkdownContent';

/**
 * Props for the MessageBubble component.
 */
export interface MessageBubbleProps {
    /** The message to render */
    message: Message;
    /** Whether to show avatar for assistant messages (default: true) */
    showAvatar?: boolean;
}

/**
 * Formats an ISO timestamp into a human-readable time string.
 * Uses locale-aware formatting for consistent display.
 *
 * @param timestamp - ISO 8601 timestamp string
 * @returns Formatted time string (e.g., "12:30 PM")
 */
function formatTime(timestamp: string): string {
    const date = new Date(timestamp);
    return date.toLocaleTimeString([], {
        hour: '2-digit',
        minute: '2-digit',
    });
}

/**
 * MessageBubble renders a single message with role-based styling.
 *
 * Validates:
 * - Requirement 2.1: Distinct visual treatments for user (right-aligned, primary color)
 *   and assistant (left-aligned, surface color) messages
 * - Requirement 2.2: Subtle shadows and rounded corners
 * - Requirement 2.3: Timestamps in subtle, secondary text style
 * - Requirement 2.7: Appropriate padding and margins for visual breathing room
 * - Requirement 2.8: Avatar/icon indicator for assistant messages
 *
 * @param props - Component props containing the message and display options
 * @returns React element representing the styled message bubble
 */
export const MessageBubble: React.FC<MessageBubbleProps> = ({
    message,
    showAvatar = true,
}) => {
    const isUser = message.role === 'user';
    const isAssistant = message.role === 'assistant';
    const isStreaming = message.isStreaming === true;

    // State for reasoning section visibility
    const [reasoningExpanded, setReasoningExpanded] = useState(false);

    // Parse message content to extract reasoning sections
    const parsedContent = useMemo(() => {
        if (isUser) {
            return { reasoning: [], content: message.content };
        }
        return parseMessage(message.content);
    }, [message.content, isUser]);

    const hasReasoning = parsedContent.reasoning.length > 0;

    return (
        <div
            className={`message-bubble message-bubble--${message.role}`}
            data-role={message.role}
            data-streaming={isStreaming || undefined}
            data-testid="message-bubble"
        >
            {/* Avatar: Only shown for assistant messages when showAvatar is true */}
            {isAssistant && showAvatar && (
                <div className="message-bubble__avatar" data-testid="message-bubble-avatar">
                    <span className="message-bubble__avatar-icon" aria-hidden="true">
                        ✦
                    </span>
                </div>
            )}

            <div className="message-bubble__content">
                {/* Reasoning section: Collapsible, small font */}
                {isAssistant && hasReasoning && (
                    <div className="message-bubble__reasoning" data-testid="message-reasoning">
                        <button
                            type="button"
                            className="message-bubble__reasoning-toggle"
                            onClick={() => setReasoningExpanded(!reasoningExpanded)}
                            aria-expanded={reasoningExpanded}
                        >
                            <span className="message-bubble__reasoning-icon">
                                {reasoningExpanded ? '▼' : '▶'}
                            </span>
                            <span className="message-bubble__reasoning-label">
                                Reasoning ({parsedContent.reasoning.length})
                            </span>
                        </button>
                        {reasoningExpanded && (
                            <div className="message-bubble__reasoning-content">
                                {parsedContent.reasoning.map((text, index) => (
                                    <div key={index} className="message-bubble__reasoning-item">
                                        {text}
                                    </div>
                                ))}
                            </div>
                        )}
                    </div>
                )}

                {/* Message text content */}
                <div className="message-bubble__text">
                    {isUser ? (
                        <p className="message-bubble__paragraph">{message.content}</p>
                    ) : (
                        <div className="message-bubble__markdown">
                            <MarkdownContent content={parsedContent.content} />
                            {/* Streaming cursor indicator */}
                            {isStreaming && (
                                <span
                                    className="message-bubble__cursor cursor-blink"
                                    aria-hidden="true"
                                    data-testid="streaming-cursor"
                                >
                                    ▊
                                </span>
                            )}
                        </div>
                    )}
                </div>

                {/* Timestamp: Shown for all messages */}
                <time
                    className="message-bubble__timestamp"
                    dateTime={message.timestamp}
                    data-testid="message-bubble-timestamp"
                >
                    {formatTime(message.timestamp)}
                </time>
            </div>
        </div>
    );
};
