// ==========================================
// ChatPane Kit — MessageBubble Component
// ==========================================
// Single message rendering with role styling, markdown,
// action toolbar, and enhanced code blocks.
// Independently importable.
//
// v0.37.10: Added message actions, timestamps, code block copy.
//
// Usage:
//   html`<${MessageBubble} role="assistant" content=${text}
//         onRegenerate=${fn} onDelete=${fn} />`

import { renderMarkdown } from './markdown.js';
import { CodeBlock, extractCodeBlocks } from './code-block.js';
import { MessageActions } from './message-actions.js';

const html = window.html;
const { useMemo } = window.hooks;

/**
 * Format a relative time string from an ISO date.
 */
function _relTime(isoDate) {
    if (!isoDate) return '';
    try {
        const d = new Date(isoDate);
        const now = Date.now();
        const sec = Math.floor((now - d.getTime()) / 1000);
        if (sec < 60) return 'just now';
        if (sec < 3600) return Math.floor(sec / 60) + 'm ago';
        if (sec < 86400) return Math.floor(sec / 3600) + 'h ago';
        return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
    } catch (_) { return ''; }
}

/**
 * @param {{
 *   role: string,
 *   content: string,
 *   thinking?: string,
 *   id?: string,
 *   created_at?: string,
 *   streaming?: boolean,
 *   onRegenerate?: () => void,
 *   onDelete?: () => void,
 * }} props
 */
export function MessageBubble({ role, content, thinking, id, created_at, streaming, onRegenerate, onDelete, isMine, senderName }) {
    // isMine: true = right-aligned (current user), false = left-aligned (other user/assistant)
    const alignment = role === 'assistant' ? 'assistant'
        : (isMine === false ? 'other' : 'user');
    const cls = 'sw-chat-msg sw-chat-msg--' + alignment
        + (streaming ? ' sw-chat-msg--streaming' : '');

    // Parse markdown and extract code blocks for enhanced rendering
    const segments = useMemo(() => {
        const rendered = renderMarkdown(content || '');
        return extractCodeBlocks(rendered);
    }, [content]);

    const thinkingHtml = useMemo(() => {
        if (!thinking) return null;
        return renderMarkdown(thinking);
    }, [thinking]);

    const timeStr = _relTime(created_at);

    // While streaming, show thinking open if content hasn't started yet
    const thinkingOpen = streaming && thinking && !content;

    return html`
        <div class=${cls}>
            ${senderName && alignment === 'other' && html`
                <div class="sw-chat-msg__sender">${senderName}</div>`}
            ${thinkingHtml && html`
                <details class="sw-chat-msg__thinking" open=${thinkingOpen || undefined}>
                    <summary class="sw-chat-msg__thinking-toggle">Thinking\u2026</summary>
                    <div class="sw-chat-msg__thinking-content"
                         dangerouslySetInnerHTML=${{ __html: thinkingHtml }} />
                </details>`}
            <div class="sw-chat-msg__content">
                ${segments.map((seg, i) =>
                    seg.type === 'code'
                        ? html`<${CodeBlock} key=${i} code=${seg.code} language=${seg.language} />`
                        : html`<span key=${i} dangerouslySetInnerHTML=${{ __html: seg.html }} />`
                )}
            </div>
            ${!streaming && html`
                <div class="sw-chat-msg__footer">
                    ${timeStr && html`<span class="sw-chat-msg__time">${timeStr}</span>`}
                    <${MessageActions}
                        role=${role}
                        content=${content}
                        onRegenerate=${onRegenerate}
                        onDelete=${onDelete} />
                </div>`}
        </div>`;
}
