'use client';

import { useState, useEffect, useRef } from 'react';
import useSWR from 'swr';
import AlertModal from './AlertModal';

interface User {
  id: string;
  email: string;
  name: string | null;
}

interface Participant {
  id: string;
  email: string;
  name: string | null;
}

interface MessageFile {
  id: string;
  filename: string;
  filepath: string;
  fileType: string;
  fileSize: number;
}

interface Message {
  id: string;
  content: string | null;
  senderId: string;
  sender: User;
  createdAt: string;
  files: MessageFile[];
}

interface Conversation {
  id: string;
  name: string | null;
  type: string;
  displayName: string;
  participants: Participant[];
}

interface ChatWindowProps {
  conversationId: string;
  conversation: Conversation;
  onNewMessage: () => void;
  onShowGroupSettings: () => void;
  onShowSidebar?: () => void;
}

const fetcher = (url: string) => fetch(url).then((res) => res.json());

export default function ChatWindow({
  conversationId,
  conversation,
  onNewMessage,
  onShowGroupSettings,
  onShowSidebar,
}: ChatWindowProps) {
  const [message, setMessage] = useState('');
  const [files, setFiles] = useState<File[]>([]);
  const [isSending, setIsSending] = useState(false);
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  const [typingUsers, setTypingUsers] = useState<User[]>([]);
  const [readReceipts, setReadReceipts] = useState<Record<string, Date | null>>({});
  const [alertModal, setAlertModal] = useState<{
    show: boolean;
    type: 'success' | 'error' | 'info' | 'warning';
    title: string;
    message: string;
  } | null>(null);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const lastTypingSignalRef = useRef<number>(0);

  // Récupérer l'utilisateur actuel
  const { data: userData } = useSWR<User>('/api/auth/me', fetcher);

  useEffect(() => {
    if (userData) {
      setCurrentUser(userData);
    }
  }, [userData]);

  const { data: messagesData, error, mutate } = useSWR<{
    messages: Message[];
    hasMore: boolean;
    cursor: string | null;
  }>(`/api/conversations/${conversationId}/messages?limit=50`, fetcher, {
    refreshInterval: 1000, // Rafraîchir toutes les secondes pour le temps réel
  });

  const messages = messagesData?.messages || [];

  // Scroll vers le bas quand de nouveaux messages arrivent
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  // Marquer les messages comme lus quand on les voit
  useEffect(() => {
    if (messages.length > 0) {
      fetch(`/api/conversations/${conversationId}/read`, {
        method: 'POST',
      }).catch(console.error);
    }
  }, [conversationId, messages.length]);

  // Récupérer les informations de lecture
  useEffect(() => {
    const fetchReadReceipts = async () => {
      try {
        const response = await fetch(`/api/conversations/${conversationId}/read`);
        if (response.ok) {
          const data = await response.json();
          const receipts: Record<string, Date | null> = {};
          data.participants.forEach((p: { userId: string; lastReadAt: string | null }) => {
            receipts[p.userId] = p.lastReadAt ? new Date(p.lastReadAt) : null;
          });
          setReadReceipts(receipts);
        }
      } catch (error) {
        console.error('Erreur lors de la récupération des lectures:', error);
      }
    };

    fetchReadReceipts();
    const interval = setInterval(fetchReadReceipts, 2000);
    return () => clearInterval(interval);
  }, [conversationId]);

  // Récupérer les utilisateurs en train d'écrire
  useEffect(() => {
    const fetchTyping = async () => {
      try {
        const response = await fetch(`/api/conversations/${conversationId}/typing`);
        if (response.ok) {
          const data = await response.json();
          setTypingUsers(data.typing || []);
        }
      } catch (error) {
        console.error('Erreur lors de la récupération du typing:', error);
      }
    };

    fetchTyping();
    const interval = setInterval(fetchTyping, 1000);
    return () => clearInterval(interval);
  }, [conversationId]);

  // Écouter les événements SSE pour les nouveaux messages
  useEffect(() => {
    const eventSource = new EventSource(`/api/conversations/${conversationId}/events`);

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data);
      if (data.type === 'new_message') {
        mutate();
        onNewMessage();
        // Marquer comme lu immédiatement
        fetch(`/api/conversations/${conversationId}/read`, {
          method: 'POST',
        }).catch(console.error);
      }
    };

    eventSource.onerror = () => {
      eventSource.close();
    };

    return () => {
      eventSource.close();
    };
  }, [conversationId, mutate, onNewMessage]);

  const handleSendMessage = async () => {
    if ((!message.trim() && files.length === 0) || isSending) return;

    setIsSending(true);
    const formData = new FormData();
    if (message.trim()) {
      formData.append('content', message);
    }
    files.forEach((file) => {
      formData.append('files', file);
    });

    try {
      const response = await fetch(`/api/conversations/${conversationId}/messages`, {
        method: 'POST',
        body: formData,
      });

      if (response.ok) {
        setMessage('');
        setFiles([]);
        if (fileInputRef.current) {
          fileInputRef.current.value = '';
        }
        mutate();
        onNewMessage();
        // Marquer comme lu immédiatement après l'envoi
        fetch(`/api/conversations/${conversationId}/read`, {
          method: 'POST',
        }).catch(console.error);
      } else {
        const error = await response.json();
        setAlertModal({
          show: true,
          type: 'error',
          title: 'Erreur',
          message: error.error || 'Erreur lors de l\'envoi du message',
        });
      }
    } catch (error) {
      console.error('Erreur:', error);
      setAlertModal({
        show: true,
        type: 'error',
        title: 'Erreur',
        message: 'Erreur lors de l\'envoi du message',
      });
    } finally {
      setIsSending(false);
    }
  };

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSendMessage();
    } else {
      // Signaler que l'utilisateur est en train d'écrire
      const now = Date.now();
      if (now - lastTypingSignalRef.current > 1000) {
        // Envoyer le signal toutes les secondes maximum
        lastTypingSignalRef.current = now;
        fetch(`/api/conversations/${conversationId}/typing`, {
          method: 'POST',
        }).catch(console.error);
      }

      // Réinitialiser le timeout
      if (typingTimeoutRef.current) {
        clearTimeout(typingTimeoutRef.current);
      }
    }
  };

  const handleMessageChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setMessage(e.target.value);

    // Signaler que l'utilisateur est en train d'écrire
    const now = Date.now();
    if (now - lastTypingSignalRef.current > 1000) {
      lastTypingSignalRef.current = now;
      fetch(`/api/conversations/${conversationId}/typing`, {
        method: 'POST',
      }).catch(console.error);
    }

    // Réinitialiser le timeout
    if (typingTimeoutRef.current) {
      clearTimeout(typingTimeoutRef.current);
    }
  };

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      setFiles(Array.from(e.target.files));
    }
  };

  const removeFile = (index: number) => {
    setFiles(files.filter((_, i) => i !== index));
  };

  const formatFileSize = (bytes: number) => {
    if (bytes < 1024) return bytes + ' B';
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
    return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
  };

  const isImageFile = (fileType: string) => {
    return fileType.startsWith('image/');
  };

  return (
    <div className="flex flex-col h-full">
      {/* En-tête */}
      <div className="p-3 md:p-4 border-b border-gray-200 flex items-center justify-between bg-white">
        <div className="flex items-center gap-2 md:gap-3 flex-1 min-w-0">
          {/* Bouton retour sur mobile */}
          {onShowSidebar && (
            <button
              onClick={onShowSidebar}
              className="p-2 rounded-lg hover:bg-gray-100 transition-colors md:hidden flex-shrink-0"
              title="Retour aux conversations"
            >
              <svg className="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
              </svg>
            </button>
          )}
          <div className="w-8 h-8 md:w-10 md:h-10 rounded-full bg-gradient-to-br from-lblue to-dblue flex items-center justify-center flex-shrink-0">
            <span className="text-white font-semibold text-xs md:text-sm">
              {conversation.type === 'group'
                ? conversation.displayName.charAt(0).toUpperCase()
                : conversation.displayName
                    .split(' ')
                    .map((n) => n.charAt(0))
                    .join('')
                    .toUpperCase()
                    .slice(0, 2)}
            </span>
          </div>
          <div className="flex-1 min-w-0">
            <h3 className="font-semibold text-gray-900 text-sm md:text-base truncate">{conversation.displayName}</h3>
            {conversation.type === 'group' && (
              <p className="text-xs text-gray-500">
                {conversation.participants.length} participant{conversation.participants.length > 1 ? 's' : ''}
              </p>
            )}
          </div>
        </div>
        {conversation.type === 'group' && (
          <button
            onClick={onShowGroupSettings}
            className="p-2 rounded-lg hover:bg-gray-100 transition-colors flex-shrink-0"
            title="Paramètres du groupe"
          >
            <svg className="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
            </svg>
          </button>
        )}
      </div>

      {/* Messages */}
      <div className="flex-1 overflow-y-auto p-2 md:p-4 bg-gray-50">
        {error && (
          <div className="text-center text-red-600 py-4">
            Erreur lors du chargement des messages
          </div>
        )}
        {!messagesData && !error && (
          <div className="text-center text-gray-500 py-4">Chargement des messages...</div>
        )}
        {messages.length === 0 && messagesData && (
          <div className="text-center text-gray-500 py-8">
            Aucun message. Commencez la conversation !
          </div>
        )}
        <div className="space-y-4">
          {messages.map((msg) => {
            const isOwnMessage = currentUser && msg.senderId === currentUser.id;
            return (
              <div
                key={msg.id}
                className={`flex ${isOwnMessage ? 'justify-end' : 'justify-start'}`}
              >
                <div
                  className={`max-w-[85%] md:max-w-[70%] rounded-lg p-2 md:p-3 ${
                    isOwnMessage
                      ? 'bg-lblue text-white'
                      : 'bg-white text-gray-900 border border-gray-200'
                  }`}
                >
                  {!isOwnMessage && conversation.type === 'group' && (
                    <div className="text-xs font-semibold mb-1 opacity-75">
                      {msg.sender.name || msg.sender.email}
                    </div>
                  )}
                  {msg.content && (
                    <p className={`text-sm whitespace-pre-wrap ${isOwnMessage ? 'text-white' : ''}`}>
                      {msg.content}
                    </p>
                  )}
                  {msg.files && msg.files.length > 0 && (
                    <div className="mt-2 space-y-2">
                      {msg.files.map((file) => (
                        <div key={file.id} className="rounded overflow-hidden">
                          {isImageFile(file.fileType) ? (
                            <a
                              href={file.filepath}
                              target="_blank"
                              rel="noopener noreferrer"
                              className="block"
                            >
                              <img
                                src={file.filepath}
                                alt={file.filename}
                                className="rounded max-w-full h-auto max-h-64"
                              />
                            </a>
                          ) : (
                            <a
                              href={file.filepath}
                              target="_blank"
                              rel="noopener noreferrer"
                              className={`flex items-center gap-2 p-2 rounded ${
                                isOwnMessage
                                  ? 'bg-white/20 hover:bg-white/30'
                                  : 'bg-gray-100 hover:bg-gray-200'
                              } transition-colors`}
                            >
                              <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path
                                  strokeLinecap="round"
                                  strokeLinejoin="round"
                                  strokeWidth={2}
                                  d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
                                />
                              </svg>
                              <div className="flex-1 min-w-0">
                                <div className="text-sm font-medium truncate">{file.filename}</div>
                                <div className="text-xs opacity-75">{formatFileSize(file.fileSize)}</div>
                              </div>
                            </a>
                          )}
                        </div>
                      ))}
                    </div>
                  )}
                  <div className={`flex items-center gap-2 mt-1 ${isOwnMessage ? 'text-white/70' : 'text-gray-500'}`}>
                    <span className="text-xs">
                      {new Date(msg.createdAt).toLocaleTimeString('fr-FR', {
                        hour: '2-digit',
                        minute: '2-digit',
                      })}
                    </span>
                    {isOwnMessage && (
                      <div className="flex items-center gap-0.5">
                        {/* Checkmarks pour les messages envoyés/lus */}
                        {(() => {
                          // Filtrer les autres participants (pas l'utilisateur actuel)
                          const otherParticipants = conversation.participants.filter(
                            (p) => p.id !== currentUser?.id
                          );
                          // Vérifier si tous les autres participants ont lu le message
                          const allRead = otherParticipants.length > 0 && otherParticipants.every((p) => {
                            const lastRead = readReceipts[p.id];
                            if (!lastRead) return false;
                            return new Date(lastRead) >= new Date(msg.createdAt);
                          });
                          
                          // Premier checkmark (toujours visible)
                          const firstCheck = (
                            <svg
                              className="w-3.5 h-3.5 text-white/70"
                              fill="none"
                              stroke="currentColor"
                              viewBox="0 0 24 24"
                            >
                              <path
                                strokeLinecap="round"
                                strokeLinejoin="round"
                                strokeWidth={2.5}
                                d="M5 13l4 4L19 7"
                              />
                            </svg>
                          );
                          
                          // Deuxième checkmark (seulement si lu)
                          const secondCheck = allRead ? (
                            <svg
                              className="w-3.5 h-3.5 text-blue-300"
                              fill="none"
                              stroke="currentColor"
                              viewBox="0 0 24 24"
                              style={{ marginLeft: '-2px' }}
                            >
                              <path
                                strokeLinecap="round"
                                strokeLinejoin="round"
                                strokeWidth={2.5}
                                d="M5 13l4 4L19 7"
                              />
                            </svg>
                          ) : null;
                          
                          return (
                            <>
                              {firstCheck}
                              {secondCheck}
                            </>
                          );
                        })()}
                      </div>
                    )}
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        {/* Indicateur de frappe */}
        {typingUsers.length > 0 && (
          <div className="flex justify-start mb-2">
            <div className="bg-white border border-gray-200 rounded-lg px-4 py-2 max-w-[70%]">
              <div className="flex items-center gap-2">
                <div className="flex gap-1">
                  <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0ms' }}></div>
                  <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '150ms' }}></div>
                  <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '300ms' }}></div>
                </div>
                <span className="text-xs text-gray-600">
                  {typingUsers.length === 1
                    ? `${typingUsers[0].name || typingUsers[0].email} est en train d'écrire...`
                    : `${typingUsers.length} personnes sont en train d'écrire...`}
                </span>
              </div>
            </div>
          </div>
        )}

        <div ref={messagesEndRef} />
      </div>

      {/* Zone de saisie */}
      <div className="p-2 md:p-4 border-t border-gray-200 bg-white">
        {/* Fichiers sélectionnés */}
        {files.length > 0 && (
          <div className="mb-2 flex flex-wrap gap-2">
            {files.map((file, index) => (
              <div
                key={index}
                className="flex items-center gap-2 bg-gray-100 rounded-lg px-2 md:px-3 py-1 md:py-2 text-xs md:text-sm"
              >
                <span className="text-gray-700 truncate max-w-[150px] md:max-w-none">{file.name}</span>
                <button
                  onClick={() => removeFile(index)}
                  className="text-red-600 hover:text-red-700 flex-shrink-0"
                >
                  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M6 18L18 6M6 6l12 12"
                    />
                  </svg>
                </button>
              </div>
            ))}
          </div>
        )}

        <div className="flex items-end gap-1 md:gap-2">
          <input
            type="file"
            ref={fileInputRef}
            onChange={handleFileSelect}
            multiple
            className="hidden"
            id="file-input"
          />
          <label
            htmlFor="file-input"
            className="p-1.5 md:p-2 rounded-lg hover:bg-gray-100 transition-colors cursor-pointer flex-shrink-0"
            title="Joindre un fichier"
          >
            <svg className="w-4 h-4 md:w-5 md:h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"
              />
            </svg>
          </label>
          <textarea
            value={message}
            onChange={handleMessageChange}
            onKeyPress={handleKeyPress}
            placeholder="Tapez votre message..."
            className="flex-1 min-h-[40px] md:min-h-[44px] max-h-32 px-3 md:px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-lblue focus:border-transparent resize-none text-sm md:text-base text-gray-900 placeholder-gray-400"
            rows={1}
          />
          <button
            onClick={handleSendMessage}
            disabled={(!message.trim() && files.length === 0) || isSending}
            className="p-1.5 md:p-2 rounded-lg bg-lblue text-white hover:bg-dblue transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex-shrink-0"
            title="Envoyer"
          >
            {isSending ? (
              <svg className="w-4 h-4 md:w-5 md:h-5 animate-spin" fill="none" viewBox="0 0 24 24">
                <circle
                  className="opacity-25"
                  cx="12"
                  cy="12"
                  r="10"
                  stroke="currentColor"
                  strokeWidth="4"
                />
                <path
                  className="opacity-75"
                  fill="currentColor"
                  d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                />
              </svg>
            ) : (
              <svg className="w-4 h-4 md:w-5 md:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
                />
              </svg>
            )}
          </button>
        </div>
      </div>

      {/* Modal d'alerte */}
      {alertModal && (
        <AlertModal
          isOpen={alertModal.show}
          type={alertModal.type}
          title={alertModal.title}
          message={alertModal.message}
          onClose={() => setAlertModal(null)}
        />
      )}
    </div>
  );
}
