import React, { useMemo, useCallback, useEffect, useRef } from 'react';
import {
  VirtualizedList,
  useInfiniteScroll,
} from '@/components/ui/virtualized-list';
import { Message } from '@/types/api';
import { sanitizeChatMessage } from '@/utils/sanitize';
import { formatDistanceToNow } from 'date-fns';
import { fr } from 'date-fns/locale';
import { logger } from '@/utils/logger';

interface VirtualizedChatMessagesProps {
  messages: Message[];
  hasNextPage: boolean;
  isFetching: boolean;
  fetchNextPage: () => void;
  className?: string;
  onMessageClick?: (message: Message) => void;
}

const MESSAGE_HEIGHT = 80; // Hauteur estimée d'un message
const CONTAINER_HEIGHT = 400; // Hauteur du conteneur de messages

export function VirtualizedChatMessages({
  messages,
  hasNextPage,
  isFetching,
  fetchNextPage,
  className = '',
  onMessageClick,
}: VirtualizedChatMessagesProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const { handleItemsRendered } = useInfiniteScroll(
    messages,
    hasNextPage,
    isFetching,
    fetchNextPage,
    5, // Charger plus quand on est à 5 messages du bas
  );

  // Mémoriser les messages pour éviter les re-renders inutiles
  const memoizedMessages = useMemo(() => messages, [messages]);

  // Rendu d'un message individuel
  const renderMessage = useCallback(
    (message: Message, index: number) => (
      <div
        key={message.id || index}
        className={`p-3 border-b border-gray-200 hover:bg-gray-50 cursor-pointer transition-colors ${
          onMessageClick ? 'hover:shadow-sm' : ''
        }`}
        onClick={() => onMessageClick?.(message)}
        style={{ minHeight: MESSAGE_HEIGHT }}
      >
        <div className="flex items-start space-x-3">
          {/* Avatar */}
          <div className="flex-shrink-0">
            <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white text-sm font-medium">
              {message.sender?.username?.charAt(0).toUpperCase() || '?'}
            </div>
          </div>

          {/* Contenu du message */}
          <div className="flex-1 min-w-0">
            <div className="flex items-center space-x-2 mb-1">
              <span className="text-sm font-medium text-gray-900">
                {message.sender?.username || 'Utilisateur inconnu'}
              </span>
              <span className="text-xs text-gray-500">
                {formatDistanceToNow(new Date(message.created_at), {
                  addSuffix: true,
                  locale: fr,
                })}
              </span>
            </div>

            {/* Contenu du message avec sanitisation */}
            <div
              className="text-sm text-gray-700 break-words"
              dangerouslySetInnerHTML={{
                __html: sanitizeChatMessage(message.content),
              }}
            />

            {/* Attachments */}
            {message.attachment_url && (
              <div className="mt-2 text-xs text-gray-500">
                <span className="inline-block px-2 py-1 bg-blue-100 text-blue-800 rounded-full">
                  📎 Pièce jointe
                </span>
              </div>
            )}
          </div>
        </div>
      </div>
    ),
    [onMessageClick],
  );

  // Gestion du scroll vers le bas pour les nouveaux messages
  const scrollToBottom = useCallback(() => {
    if (containerRef.current) {
      containerRef.current.scrollTop = containerRef.current.scrollHeight;
    }
  }, []);

  // Auto-scroll vers le bas quand de nouveaux messages arrivent
  useEffect(() => {
    if (!isFetching && messages.length > 0) {
      const lastMessage = messages[messages.length - 1];
      const isRecentMessage =
        Date.now() - new Date(lastMessage.created_at).getTime() < 5000; // 5 secondes

      if (isRecentMessage) {
        scrollToBottom();
      }
    }
  }, [messages.length, isFetching, scrollToBottom]);

  // Indicateur de chargement
  const loadingIndicator = useMemo(() => {
    if (!isFetching) return null;

    return (
      <div className="flex justify-center items-center py-4">
        <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500"></div>
        <span className="ml-2 text-sm text-gray-500">
          Chargement des messages...
        </span>
      </div>
    );
  }, [isFetching]);

  // Message vide
  if (messages.length === 0 && !isFetching) {
    return (
      <div className={`flex items-center justify-center h-full ${className}`}>
        <div className="text-center">
          <div className="text-gray-400 text-6xl mb-4">💬</div>
          <p className="text-gray-500">Aucun message dans cette conversation</p>
          <p className="text-sm text-gray-400 mt-2">
            Soyez le premier à envoyer un message !
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className={`relative ${className}`}>
      {/* Indicateur de chargement en haut */}
      {isFetching && hasNextPage && (
        <div className="absolute top-0 left-0 right-0 z-10 bg-white/80 backdrop-blur-sm">
          {loadingIndicator}
        </div>
      )}

      {/* Liste virtualisée des messages */}
      <VirtualizedList
        ref={containerRef}
        items={memoizedMessages}
        itemHeight={MESSAGE_HEIGHT}
        containerHeight={CONTAINER_HEIGHT}
        renderItem={renderMessage}
        onItemsRendered={handleItemsRendered}
        className="scroll-smooth"
        overscan={10}
      />

      {/* Bouton pour revenir en bas */}
      <button
        onClick={scrollToBottom}
        className="absolute bottom-4 right-4 bg-blue-500 hover:bg-blue-600 text-white rounded-full p-2 shadow-lg transition-colors"
        title="Revenir en bas"
      >
        <svg
          className="w-5 h-5"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M19 14l-7 7m0 0l-7-7m7 7V3"
          />
        </svg>
      </button>
    </div>
  );
}

// Hook pour gérer l'état des messages avec pagination
// ... imports
import { apiClient } from '@/services/api/client';

// ... (props interface same)

// ... (VirtualizedChatMessages component)
// Replace message.user with message.sender
// Remove metadata/is_edited/is_deleted if not in type OR cast/guard if expected

// Hook pour gérer l'état des messages avec pagination
export function useChatMessages(conversationId: string) {
  const [messages, setMessages] = React.useState<Message[]>([]);
  const [hasNextPage, setHasNextPage] = React.useState(true);
  const [isFetching, setIsFetching] = React.useState(false);
  const [page, setPage] = React.useState(1);

  const fetchMessages = useCallback(
    async (pageNum: number = 1) => {
      if (isFetching) return;

      setIsFetching(true);
      try {
        // Use apiClient.get for messages
        const response = await apiClient.get<{ data: Message[] }>('/messages', {
          params: {
            conversation_id: conversationId,
            page: pageNum,
            limit: 50,
          },
        });
        // apiClient unwrap déjà le format { success, data }
        const data = response.data;
        const newMessages = (data.data as unknown as Message[]) || [];
        // Note: has_next peut être dans data si c'est une PaginatedResponse
        const paginatedData = data as any;

        if (pageNum === 1) {
          setMessages(newMessages);
        } else {
          setMessages((prev) => [...newMessages, ...prev]);
        }

        setHasNextPage(paginatedData.has_next || false);
        setPage(pageNum);
      } catch (error) {
        logger.error('Erreur lors du chargement des messages:', { error });
      } finally {
        setIsFetching(false);
      }
    },
    [conversationId, isFetching],
  );
  // ...

  const fetchNextPage = useCallback(() => {
    if (hasNextPage && !isFetching) {
      fetchMessages(page + 1);
    }
  }, [hasNextPage, isFetching, fetchMessages, page]);

  const addMessage = useCallback((message: Message) => {
    setMessages((prev) => [...prev, message]);
  }, []);

  const updateMessage = useCallback(
    (messageId: string, updates: Partial<Message>) => {
      setMessages((prev) =>
        prev.map((msg) =>
          msg.id === messageId ? { ...msg, ...updates } : msg,
        ),
      );
    },
    [],
  );

  const deleteMessage = useCallback((messageId: string) => {
    setMessages((prev) => prev.filter((msg) => msg.id !== messageId));
  }, []);

  // Charger les messages au montage
  useEffect(() => {
    fetchMessages(1);
  }, [conversationId]);

  return {
    messages,
    hasNextPage,
    isFetching,
    fetchNextPage,
    addMessage,
    updateMessage,
    deleteMessage,
  };
}
