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

/**
 * MessageList Component
 *
 * Renders the list of chat messages with auto-scroll functionality.
 * Displays a welcome message when the conversation is empty.
 *
 * Features:
 * - Smooth scroll behavior when new messages arrive (Requirement 8.3)
 * - Design system tokens for consistent spacing and styling
 * - Auto-scroll to bottom on new messages or streaming updates
 * - SSR-safe implementation (browser APIs guarded with useEffect)
 *
 * @requirements 8.3
 */

import * as React from 'react';
import { useRef, useEffect, useCallback } from 'react';
import { MessageItem } from './MessageItem';
import type { Message } from '../../types';

interface MessageListProps {
    /** Array of messages to display */
    messages: Message[];
    /** Whether a response is currently being generated */
    isLoading: boolean;
}

/**
 * MessageList component displays the conversation history with smooth scrolling.
 *
 * Uses CSS scroll-behavior for smooth scrolling and JavaScript scrollIntoView
 * as a fallback for programmatic scroll control.
 */
export const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {
    const listRef = useRef<HTMLDivElement>(null);
    const bottomRef = useRef<HTMLDivElement>(null);
    const prevMessageCountRef = useRef<number>(messages.length);

    /**
     * Scrolls to the bottom of the message list with smooth behavior.
     * Uses scrollIntoView with smooth behavior for cross-browser compatibility.
     * Respects prefers-reduced-motion by using 'auto' behavior when reduced motion is preferred.
     */
    const scrollToBottom = useCallback(() => {
        if (typeof window === 'undefined') return;

        const bottomElement = bottomRef.current;
        if (!bottomElement) return;

        // Check for reduced motion preference
        const prefersReducedMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;

        bottomElement.scrollIntoView({
            behavior: prefersReducedMotion ? 'auto' : 'smooth',
            block: 'end',
        });
    }, []);

    // Auto-scroll to bottom when new messages arrive or during streaming
    useEffect(() => {
        const messageCountChanged = messages.length !== prevMessageCountRef.current;
        const hasMessages = messages.length > 0;

        // Scroll when:
        // 1. New message is added
        // 2. Loading state changes (streaming updates)
        if ((messageCountChanged || isLoading) && hasMessages) {
            scrollToBottom();
        }

        prevMessageCountRef.current = messages.length;
    }, [messages, isLoading, scrollToBottom]);

    // Display welcome message for empty conversation state
    if (messages.length === 0 && !isLoading) {
        return (
            <div className="message-list message-list--empty" role="region" aria-label="Chat messages">
                <div className="welcome-message">
                    <div className="welcome-message__icon" aria-hidden="true">
                        <span className="welcome-message__sparkle">✦</span>
                    </div>
                    <h2 className="welcome-message__title">Welcome to AI Chat</h2>
                    <p className="welcome-message__description">
                        Start a conversation by typing a message below.
                    </p>
                </div>
            </div>
        );
    }

    return (
        <div
            className="message-list"
            ref={listRef}
            role="log"
            aria-label="Chat messages"
            aria-live="polite"
            aria-relevant="additions"
        >
            {messages.map((message) => (
                <MessageItem key={message.id} message={message} />
            ))}
            {/* Scroll anchor element for smooth scrolling to bottom */}
            <div
                ref={bottomRef}
                className="message-list__scroll-anchor"
                aria-hidden="true"
            />
        </div>
    );
};
