import React, { useEffect, useRef, useMemo, useCallback } from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import CircularProgress from '@mui/material/CircularProgress';
import { ChatMessage, ChatUser } from '../../types/chat';
import ChatBubble from './ChatBubble';
import UserAvatar from '../UserAvatar';

interface ChatMessagesProps {
  messages: ChatMessage[];
  currentUserId: number;
  participants: ChatUser[];
  loading?: boolean;
  typingUsers?: number[];
  hasMore?: boolean;
  onLoadMore?: () => void;
}

const ChatMessages: React.FC<ChatMessagesProps> = ({
  messages,
  currentUserId,
  participants,
  loading = false,
  typingUsers = [],
  hasMore = false,
  onLoadMore,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const bottomRef = useRef<HTMLDivElement>(null);
  const prevMessagesLengthRef = useRef(messages.length);
  const isLoadingMoreRef = useRef(false);

  // Auto-scroll to bottom on new messages (only for new messages at the end)
  useEffect(() => {
    // Only auto-scroll if messages were added at the end (not loaded from top)
    if (messages.length > prevMessagesLengthRef.current && !isLoadingMoreRef.current) {
      bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
    }
    prevMessagesLengthRef.current = messages.length;
    isLoadingMoreRef.current = false;
  }, [messages.length]);

  // Handle scroll to detect when user reaches the top
  const handleScroll = useCallback(() => {
    const container = containerRef.current;
    if (!container || loading || !hasMore || !onLoadMore) return;

    // Load more when scrolled near the top (within 50px)
    if (container.scrollTop < 50) {
      isLoadingMoreRef.current = true;
      onLoadMore();
    }
  }, [loading, hasMore, onLoadMore]);

  // Get participant by ID
  const getParticipant = (userId: number): ChatUser | undefined => {
    return participants.find(p => p.id === userId);
  };

  // Format date separator
  const formatDateSeparator = (timestamp: string): string => {
    const date = new Date(timestamp);
    const today = new Date();
    const yesterday = new Date(today);
    yesterday.setDate(yesterday.getDate() - 1);

    if (date.toDateString() === today.toDateString()) {
      return 'Heute';
    }
    if (date.toDateString() === yesterday.toDateString()) {
      return 'Gestern';
    }
    return date.toLocaleDateString('de-DE', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
    });
  };

  // Group messages by date and consecutive sender
  const groupedMessages = useMemo(() => {
    const groups: Array<{
      type: 'date' | 'messages';
      date?: string;
      messages?: Array<{
        message: ChatMessage;
        showAvatar: boolean;
      }>;
    }> = [];

    let currentDate = '';
    let currentSenderId: number | null = null;
    let currentGroup: Array<{ message: ChatMessage; showAvatar: boolean }> = [];

    messages.forEach((message, index) => {
      const messageDate = new Date(message.timestamp).toDateString();

      // Add date separator if date changed
      if (messageDate !== currentDate) {
        if (currentGroup.length > 0) {
          groups.push({ type: 'messages', messages: currentGroup });
          currentGroup = [];
        }
        groups.push({ type: 'date', date: formatDateSeparator(message.timestamp) });
        currentDate = messageDate;
        currentSenderId = null;
      }

      // Check if we should show avatar (last message in consecutive group from same sender)
      const nextMessage = messages[index + 1];
      const isLastInGroup =
        !nextMessage ||
        nextMessage.senderId !== message.senderId ||
        new Date(nextMessage.timestamp).toDateString() !== messageDate;

      // If sender changed, finalize previous group
      if (message.senderId !== currentSenderId) {
        if (currentGroup.length > 0) {
          groups.push({ type: 'messages', messages: currentGroup });
          currentGroup = [];
        }
        currentSenderId = message.senderId;
      }

      currentGroup.push({
        message,
        showAvatar: isLastInGroup && message.senderId !== currentUserId,
      });
    });

    // Add final group
    if (currentGroup.length > 0) {
      groups.push({ type: 'messages', messages: currentGroup });
    }

    return groups;
  }, [messages, currentUserId]);

  // Get typing indicator text
  const typingText = useMemo(() => {
    if (typingUsers.length === 0) return null;

    const typingParticipants = typingUsers
      .filter(id => id !== currentUserId)
      .map(id => getParticipant(id)?.name?.split(' ')[0] || 'Jemand');

    if (typingParticipants.length === 0) return null;
    if (typingParticipants.length === 1) {
      return `${typingParticipants[0]} tippt...`;
    }
    return `${typingParticipants.join(', ')} tippen...`;
  }, [typingUsers, participants, currentUserId]);

  return (
    <Box
      ref={containerRef}
      onScroll={handleScroll}
      sx={{
        flex: 1,
        overflowY: 'auto',
        overflowX: 'hidden',
        py: 1,
        backgroundColor: '#ffffff',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      {/* Loading indicator at top for loading more messages */}
      {hasMore && (
        <Box sx={{ display: 'flex', justifyContent: 'center', py: 1 }}>
          <Typography variant="caption" sx={{ color: '#6c757d', cursor: 'pointer' }} onClick={onLoadMore}>
            Ältere Nachrichten laden...
          </Typography>
        </Box>
      )}

      {loading && (
        <Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}>
          <CircularProgress size={24} />
        </Box>
      )}

      {!loading && messages.length === 0 && (
        <Box
          sx={{
            flex: 1,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            color: '#495057',
          }}
        >
          <Typography variant="body2">
            Noch keine Nachrichten
          </Typography>
        </Box>
      )}

      {groupedMessages.map((group, groupIndex) => {
        if (group.type === 'date') {
          return (
            <Box
              key={`date-${groupIndex}`}
              sx={{
                display: 'flex',
                justifyContent: 'center',
                my: 1,
              }}
            >
              <Typography
                variant="caption"
                sx={{
                  px: 1.5,
                  py: 0.5,
                  backgroundColor: '#f0f0f0',
                  borderRadius: '12px',
                  color: '#495057',
                  fontSize: '11px',
                }}
              >
                {group.date}
              </Typography>
            </Box>
          );
        }

        return (
          <React.Fragment key={`group-${groupIndex}`}>
            {group.messages?.map(({ message, showAvatar }) => {
              const participant = getParticipant(message.senderId);
              const isOwnMessage = message.senderId === currentUserId;

              return (
                <ChatBubble
                  key={message.id}
                  message={message}
                  isOwnMessage={isOwnMessage}
                  showAvatar={showAvatar}
                  avatar={
                    participant && (
                      <UserAvatar
                        photoUrl={participant.avatar}
                        initials={participant.name.substring(0, 2).toUpperCase()}
                        fullName={participant.name}
                        sx={{ width: 28, height: 28, fontSize: '12px' }}
                      />
                    )
                  }
                />
              );
            })}
          </React.Fragment>
        );
      })}

      {/* Typing indicator */}
      {typingText && (
        <Box sx={{ px: 1.5, py: 0.5 }}>
          <Typography
            variant="caption"
            sx={{ color: '#495057', fontStyle: 'italic' }}
          >
            {typingText}
          </Typography>
        </Box>
      )}

      {/* Scroll anchor */}
      <div ref={bottomRef} />
    </Box>
  );
};

export default ChatMessages;
