/**
 * MessageList Component
 * Virtualized message list with auto-scroll and performance optimization
 */

import React, { useRef, useEffect, useCallback, useState } from 'react';
import { ArrowDown, Loader2 } from 'lucide-react';
import ChatMessage from './ChatMessage';

export interface Message {
  id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  timestamp: string;
  isStreaming?: boolean;
  toolCalls?: ToolCall[];
  error?: string;
  metadata?: Record<string, unknown>;
}

interface ToolCall {
  id: string;
  name: string;
  status: 'pending' | 'running' | 'success' | 'error';
  result?: unknown;
}

interface MessageListProps {
  messages: Message[];
  isLoading?: boolean;
  onRetry?: (messageId: string) => void;
  onFeedback?: (messageId: string, positive: boolean) => void;
  onSignalExecute?: (signal: unknown) => void;
  highlightedMessageId?: string;
  searchQuery?: string;
  compact?: boolean;
}

const MessageList: React.FC<MessageListProps> = ({
  messages,
  isLoading = false,
  onRetry,
  onFeedback,
  onSignalExecute,
  highlightedMessageId,
  searchQuery,
  compact = false,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const bottomRef = useRef<HTMLDivElement>(null);
  const [showScrollButton, setShowScrollButton] = useState(false);
  const [autoScroll, setAutoScroll] = useState(true);

  // Check if user has scrolled away from bottom
  const handleScroll = useCallback(() => {
    if (!containerRef.current) return;

    const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
    const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
    const isNearBottom = distanceFromBottom < 100;

    setShowScrollButton(!isNearBottom);
    setAutoScroll(isNearBottom);
  }, []);

  // Scroll to bottom
  const scrollToBottom = useCallback((smooth = true) => {
    bottomRef.current?.scrollIntoView({
      behavior: smooth ? 'smooth' : 'auto',
      block: 'end',
    });
    setShowScrollButton(false);
    setAutoScroll(true);
  }, []);

  // Scroll to highlighted message
  const scrollToMessage = useCallback((messageId: string) => {
    const element = document.getElementById(`message-${messageId}`);
    if (element) {
      element.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
  }, []);

  // Auto-scroll when new messages arrive (if user hasn't scrolled up)
  useEffect(() => {
    if (autoScroll && messages.length > 0) {
      scrollToBottom(false);
    }
  }, [messages.length, autoScroll, scrollToBottom]);

  // Scroll to highlighted message when it changes
  useEffect(() => {
    if (highlightedMessageId) {
      scrollToMessage(highlightedMessageId);
    }
  }, [highlightedMessageId, scrollToMessage]);

  // Filter and highlight messages based on search
  const filteredMessages = searchQuery
    ? messages.filter((msg) =>
        msg.content.toLowerCase().includes(searchQuery.toLowerCase())
      )
    : messages;

  // Highlight search matches in content
  const highlightText = (text: string, query: string): React.ReactNode => {
    if (!query) return text;

    const parts = text.split(new RegExp(`(${query})`, 'gi'));
    return parts.map((part, index) =>
      part.toLowerCase() === query.toLowerCase() ? (
        <mark key={index} className="bg-yellow-500/30 text-yellow-200 px-0.5 rounded">
          {part}
        </mark>
      ) : (
        part
      )
    );
  };

  if (messages.length === 0 && !isLoading) {
    return (
      <div className="flex-1 flex items-center justify-center p-8">
        <div className="text-center">
          <div className="w-16 h-16 mx-auto mb-4 rounded-full bg-gray-800 flex items-center justify-center">
            <svg className="w-8 h-8 text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z" />
            </svg>
          </div>
          <h3 className="text-lg font-medium text-white mb-2">Start a Conversation</h3>
          <p className="text-gray-400 text-sm max-w-sm">
            Ask me about trading strategies, market analysis, or get help with your portfolio.
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="relative flex-1 flex flex-col min-h-0">
      {/* Search Results Summary */}
      {searchQuery && (
        <div className="px-4 py-2 bg-yellow-500/10 border-b border-yellow-500/30">
          <span className="text-sm text-yellow-400">
            Found {filteredMessages.length} message{filteredMessages.length !== 1 ? 's' : ''} matching "{searchQuery}"
          </span>
        </div>
      )}

      {/* Messages Container */}
      <div
        ref={containerRef}
        onScroll={handleScroll}
        className={`flex-1 overflow-y-auto ${compact ? 'px-3 py-2' : 'px-4 py-4'}`}
      >
        <div className="max-w-4xl mx-auto space-y-4">
          {filteredMessages.map((message, index) => (
            <div
              key={message.id}
              id={`message-${message.id}`}
              className={`transition-all duration-200 ${
                highlightedMessageId === message.id
                  ? 'ring-2 ring-blue-500 ring-offset-2 ring-offset-gray-900 rounded-lg'
                  : ''
              }`}
            >
              <ChatMessage
                message={{
                  ...message,
                  timestamp: new Date(message.timestamp),
                  content: searchQuery
                    ? String(highlightText(message.content, searchQuery))
                    : message.content,
                }}
                isLast={index === filteredMessages.length - 1}
                onRetry={onRetry ? () => onRetry(message.id) : undefined}
                onFeedback={
                  onFeedback && message.role === 'assistant'
                    ? (positive: boolean) => onFeedback(message.id, positive)
                    : undefined
                }
                onSignalExecute={onSignalExecute}
                compact={compact}
              />
            </div>
          ))}

          {/* Loading Indicator */}
          {isLoading && (
            <div className="flex items-center gap-3 p-4">
              <div className="w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center">
                <Loader2 className="w-4 h-4 text-white animate-spin" />
              </div>
              <div className="flex-1">
                <div className="h-4 bg-gray-700 rounded w-3/4 animate-pulse" />
                <div className="h-3 bg-gray-700 rounded w-1/2 animate-pulse mt-2" />
              </div>
            </div>
          )}

          {/* Bottom anchor for scrolling */}
          <div ref={bottomRef} />
        </div>
      </div>

      {/* Scroll to Bottom Button */}
      {showScrollButton && (
        <button
          onClick={() => scrollToBottom(true)}
          className="absolute bottom-4 right-4 p-2 bg-blue-600 hover:bg-blue-500 text-white rounded-full shadow-lg transition-all transform hover:scale-105"
          aria-label="Scroll to bottom"
        >
          <ArrowDown className="w-5 h-5" />
        </button>
      )}
    </div>
  );
};

export default MessageList;
