import React, { useState, useEffect, useRef } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { useQueryClient } from '@tanstack/react-query';

// Hooks
import { useWebSocketNotifications } from "@/hooks/use-websocket-notifications";
import { useContactData } from "@/hooks/useContactData";
import { useMessages } from "@/hooks/useMessages";
import { useChatActions } from "@/hooks/useChatActions";
import { useUser } from "@/hooks/use-user";
import { useKeyboardViewport } from "@/hooks/useKeyboardViewport";
// Utils
import { isAdmin } from "@/lib/user-utils";
import { cleanPhoneNumber } from "@/utils/phoneUtils";
import { clearFileInput } from '@/utils/fileHelpers';
import { generateVideoThumbnail } from '@/utils/videoUtils';

// Components
import Header from './Chat/Header';
import InputArea from './Chat/InputArea';
import MessageList from './Chat/MessageList';
import FilePreview from './Chat/FilePreview';

interface Contact {
  id: number;
  name: string;
  phone: string;
  urlAvatar?: string;
  country?: string;
}

interface Message {
  id: number;
  message_id: string;
  main_id?: string;
  webhook_from: string;
  webhook_to: string;
  webhook_body?: string;
  webhook_type: string;
  webhook_data?: any;
  from_me: boolean;
  author?: string;
  push_name?: string;
  event_type: string;
  ack?: string;
  hash?: string;
  media_url?: string;
  filename?: string;
  id_thread?: string;
  assistant_ignored: boolean;
  read: boolean;
  created_at: string;
  optimistic_id?: string; // Client-side generated ID for optimistic UI updates
  reactions?: MessageReaction[];
  isHumbertoMaturanaMessage?: boolean; // Flag for Humberto Maturana messages
  specialMessage?: boolean; // Flag for special messages requiring highlighting
  pending?: boolean; // Flag for pending assistant messages that need review
}

interface MessageReaction {
  id: number;
  message_id: string;
  emoji: string;
  webhook_from: string;
  created_at: string;
}

interface MessagingInterfaceProps {
  contact: Contact;
  onClose: () => void;
  embedded?: boolean; // New prop to control embedded mode
  showBackButton?: boolean; // New prop to show back button on mobile
  onBack?: () => void; // New prop for back button callback
}

const MessagingInterface: React.FC<MessagingInterfaceProps> = ({ contact, onClose, embedded = false, showBackButton = false, onBack }) => {
  const { id: contactId, name: contactName, phone: contactPhone, urlAvatar: contactAvatar } = contact;
  
  // Clean component without debug logging
  
  // Use custom hooks for data fetching and actions - optimized with parallel loading
  const { data: contactData } = useContactData(contactId);
  const { messages, isLoading: messagesLoading, fetchNextPage, hasNextPage, isFetchingNextPage } = useMessages(contactPhone);
  const chatActions = useChatActions(contactPhone, contactId);
  const { user } = useUser();
  const queryClient = useQueryClient();
  
  // Mobile keyboard viewport detection
  const { isKeyboardOpen, keyboardHeight } = useKeyboardViewport();
  

  
  // Local UI state only
  const [message, setMessage] = useState('');
  const [isEmojiPickerOpen, setIsEmojiPickerOpen] = useState(false);
  const [assistantEnabled, setAssistantEnabled] = useState(false);
  const [assistantMode, setAssistantMode] = useState<'automated' | 'hybrid'>('hybrid');
  const [reviewGuardEnabled, setReviewGuardEnabled] = useState(false);
  const [engagement, setEngagement] = useState<string>('Hot');
  const [isLoading, setIsLoading] = useState(false);
  // Separate state for media files (images/videos) vs documents as per documentation
  const [selectedMediaFile, setSelectedMediaFile] = useState<File | null>(null);
  const [mediaPreview, setMediaPreview] = useState<string | null>(null);
  const [videoThumbnail, setVideoThumbnail] = useState<string | null>(null);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [filePreview, setFilePreview] = useState<string | null>(null);
  const [isMediaPreviewFading, setIsMediaPreviewFading] = useState(false);
  const [isFilePreviewFading, setIsFilePreviewFading] = useState(false);
  const [videoSizeError, setVideoSizeError] = useState<string | null>(null);
  const [isInitialLoad, setIsInitialLoad] = useState(true);
  const [hasInitializedScroll, setHasInitializedScroll] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const photoInputRef = useRef<HTMLInputElement>(null);
  // Hover state for message interactions
  const [hoveredMessageId, setHoveredMessageId] = useState<string | null>(null);
  const { clearNotification } = useWebSocketNotifications();
  
  // Track if we've already marked messages as read for this contact to prevent loops
  const hasMarkedAsReadRef = useRef<string | null>(null);

  // Reset scroll state when contact changes
  useEffect(() => {
    setIsInitialLoad(true);
    setHasInitializedScroll(false);
  }, [contactPhone]);

  // Mark scroll as initialized once messages load and scroll completes
  useEffect(() => {
    if (messages && messages.length > 0 && isInitialLoad && !hasInitializedScroll) {
      // Small delay to ensure MessageList has had time to scroll
      const timer = setTimeout(() => {
        setHasInitializedScroll(true);
        setIsInitialLoad(false);
      }, 500);
      return () => clearTimeout(timer);
    }
  }, [messages, isInitialLoad, hasInitializedScroll]);

  // Helper function to get engagement badge colors (matching AdminContactsPage)
  const getEngagementColor = (engagement: string) => {
    switch (engagement.toLowerCase()) {
      case 'hot':
        return 'bg-red-50 text-red-700';
      case 'warm':
        return 'bg-orange-50 text-orange-700';
      case 'cold':
        return 'bg-blue-50 text-blue-700';
      case 'medium':
        return 'bg-yellow-50 text-yellow-700';
      default:
        return 'bg-gray-50 text-gray-700';
    }
  };



  // Data fetching now handled by custom hooks

  // WebSocket connection for real-time updates
  useWebSocketNotifications();

  // Clear notification and mark messages as read when chat is opened (only once per contact)
  useEffect(() => {
    const phoneNumber = contactPhone.replace('@c.us', '').replace('@s.whatsapp.net', '');
    
    // Only mark as read if we haven't already done so for this contact
    if (hasMarkedAsReadRef.current === contactPhone) {
      return;
    }
    
    // Use the consolidated mark-read utility to clear notification and mark as read
    const markAsRead = async () => {
      try {
        const { markReadManager } = await import('@/utils/markReadUtils');
        markReadManager.setQueryClient(queryClient);
        await markReadManager.markMessagesAsRead(phoneNumber);
        clearNotification(phoneNumber);
        // Mark this contact as having been processed
        hasMarkedAsReadRef.current = contactPhone;
      } catch (error) {
        console.error('Error marking messages as read:', error);
      }
    };
    
    markAsRead();
  }, [contactPhone, clearNotification]); // Only run when contactPhone changes

  // WebSocket logic now handled by useMessages hook

  // Smooth fade out function for upload previews
  const fadeOutAndClearMedia = async () => {
    setIsMediaPreviewFading(true);
    await new Promise(resolve => setTimeout(resolve, 300)); // Wait for fade animation
    setSelectedMediaFile(null);
    setMediaPreview(null);
    setVideoThumbnail(null);
    setIsMediaPreviewFading(false);
  };

  const fadeOutAndClearFile = async () => {
    setIsFilePreviewFading(true);
    await new Promise(resolve => setTimeout(resolve, 300)); // Wait for fade animation
    setSelectedFile(null);
    setFilePreview(null);
    setIsFilePreviewFading(false);
  };

  // Scroll logic is now handled by MessageList component with infinite scroll support

  // Mutation logic now handled by useChatActions hook

  // Extract mutations and loading states from chat actions hook
  const { 
    sendTextMutation, 
    sendMediaMutation, 
    sendFileMutation, 
    updateEngagementMutation, 
    toggleAssistantMutation, 
    toggleAssistantModeMutation,
    resetChatMutation,
    isSendingText,
    isSendingMedia,
    isSendingFile,
    isUpdatingEngagement,
    isTogglingAssistant,
    isTogglingAssistantMode,
    isResettingChat
  } = chatActions;





  // Update assistant state when contact data changes
  useEffect(() => {
    if (contactData) {
      setAssistantEnabled(contactData.assistant || false);
      setAssistantMode(contactData.assistantMode || 'hybrid');
      setReviewGuardEnabled(contactData.reviewGuard || false);
      setEngagement(contactData.engagement || 'Hot');
    }
  }, [contactData]);

  // Scroll behavior is now handled by MessageList component





  // Helper functions now imported from utils

  // Handle document file selection (PDFs, Word docs, etc.) - separate workflow
  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      // Clear any selected media
      setSelectedMediaFile(null);
      setMediaPreview(null);
      
      // Set document file
      setSelectedFile(file);
      setFilePreview(null); // Documents don't show image previews
    }
  };

  // Video thumbnail generation now handled by videoUtils

  // Handle media selection (images and videos) - separate workflow
  const handlePhotoSelect = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      // Clear any previous video size error
      setVideoSizeError(null);
      
      // Check video file size limit (16MB)
      if (file.type.startsWith('video/') && file.size > 16 * 1024 * 1024) {
        // Show friendly error in video preview section
        setVideoSizeError('Video too large! Max size: 16MB');
        setSelectedMediaFile(file); // Still set the file to show in preview
        setMediaPreview(null);
        setVideoThumbnail(null);
        return;
      }
      
      // Clear any selected document
      setSelectedFile(null);
      setFilePreview(null);
      
      // Set media file
      setSelectedMediaFile(file);
      
      // Generate preview for images and videos
      if (file.type.startsWith('image/')) {
        const reader = new FileReader();
        reader.onload = () => {
          setMediaPreview(reader.result as string);
        };
        reader.readAsDataURL(file);
        setVideoThumbnail(null);
      } else if (file.type.startsWith('video/')) {
        setMediaPreview(URL.createObjectURL(file));
        // Generate video thumbnail
        try {
          const thumbnail = await generateVideoThumbnail(file);
          setVideoThumbnail(thumbnail);
        } catch (error) {
          console.error('Error generating video thumbnail:', error);
          setVideoThumbnail(null);
        }
      } else {
        setMediaPreview(null);
        setVideoThumbnail(null);
      }
    }
  };

  // Clear selected files
  const clearSelectedFile = () => {
    setSelectedFile(null);
    setFilePreview(null);
    clearFileInput(fileInputRef);
  };

  // Clear selected media files
  const clearSelectedMediaFile = () => {
    setSelectedMediaFile(null);
    setMediaPreview(null);
    setVideoThumbnail(null);
    setVideoSizeError(null);
    clearFileInput(photoInputRef);
  };

  // Handle send message - routes to appropriate endpoint based on file type
  const handleSendMessage = async () => {
    const messageText = message.trim();
    
    // Don't send empty messages without media/files
    if (!messageText && !selectedMediaFile && !selectedFile) {
      return;
    }
    
    // Generate a unique optimistic ID for this message
    const optimisticId = uuidv4();
    
    try {
      // Route to appropriate mutation based on what's selected
      if (selectedMediaFile) {
        // Send media (images/videos) via /api/whatsapp/send-media
        await sendMediaMutation.mutateAsync({ 
          mediaFile: selectedMediaFile, 
          caption: messageText || undefined,
          optimisticId: optimisticId
        });
        
        // Clear message and media after successful send
        setMessage('');
        await fadeOutAndClearMedia();
      } else if (selectedFile) {
        // Send document (PDFs, Word docs, etc.) via /api/whatsapp/send-file
        await sendFileMutation.mutateAsync({ 
          documentFile: selectedFile, 
          caption: messageText || undefined,
          optimisticId: optimisticId
        });
        
        // Clear message and file after successful send
        setMessage('');
        await fadeOutAndClearFile();
      } else if (messageText) {
        // Send text-only message via /api/whatsapp/send
        await sendTextMutation.mutateAsync({ 
          text: messageText, 
          optimisticId: optimisticId 
        });
        
        // Clear message after successful send
        setMessage('');
      }
    } catch (error) {
      // Error handling is already managed by the mutation's onError callback
      console.error('Error sending message:', error);
    }
  };





  // Toggle assistant
  const handleToggleAssistant = (enabled: boolean) => {
    setAssistantEnabled(enabled);
    toggleAssistantMutation.mutate(enabled);
  };

  // Toggle assistant mode
  const handleToggleAssistantMode = (mode: 'automated' | 'hybrid') => {
    setAssistantMode(mode);
    toggleAssistantModeMutation.mutate(mode);
  };

  // Toggle review guard
  const handleToggleReviewGuard = (enabled: boolean) => {
    setReviewGuardEnabled(enabled);
    chatActions.toggleReviewGuardMutation.mutate(enabled);
  };

  // Handle engagement change
  const handleEngagementChange = (newEngagement: string) => {
    updateEngagementMutation.mutate(newEngagement);
  };

  // Pending message handlers
  const handleEditPendingMessage = (messageId: string, newBody: string) => {
    chatActions.editPendingMessage({ messageId, webhookBody: newBody });
  };

  const handleSendPendingMessage = (messageId: string) => {
    // Generate optimistic ID for proper ACK matching
    const optimisticId = `optimistic_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    chatActions.sendPendingMessage({ messageId, optimisticId });
  };

  const handleDiscardPendingMessage = (messageId: string) => {
    chatActions.discardPendingMessage({ messageId });
  };

  const handleRerunPendingMessage = (messageId: string) => {
    chatActions.rerunAssistant({ messageId });
  };

  // Formatting functions now imported from utils

  // Country flag utility now imported from utils

  // URL detection functions now imported from utils

  // ACK badge now handled by AckBadge component

  const isMobileKeyboardOpen = embedded && isKeyboardOpen;

  return (
    <div className={embedded ? "h-full flex flex-col relative" : "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"}>
      <div className={embedded ? "bg-white h-full flex flex-col w-full" : "bg-white rounded-lg shadow-xl w-full max-w-4xl h-5/6 flex flex-col overflow-hidden"}>
        {/* Header */}
        <Header
          contactId={contactId}
          contactName={contactName}
          contactPhone={contactPhone}
          contactAvatarUrl={contactAvatar || contactData?.urlAvatar}
          countryCode={contact.country || contactData?.country}
          engagement={engagement}
          onEngagementChange={handleEngagementChange}
          assistantEnabled={assistantEnabled}
          assistantMode={assistantMode}
          onToggleAssistant={handleToggleAssistant}
          onToggleAssistantMode={handleToggleAssistantMode}
          reviewGuardEnabled={reviewGuardEnabled}
          onToggleReviewGuard={handleToggleReviewGuard}
          isReviewGuardLoading={chatActions.isTogglingReviewGuard}
          isUserAdmin={isAdmin(user)}
          onResetChat={() => resetChatMutation.mutate()}
          onClose={onClose}
          embedded={embedded}
          isEngagementLoading={isUpdatingEngagement}
          isAssistantLoading={isTogglingAssistant}
          isAssistantModeLoading={isTogglingAssistantMode}
          isResetLoading={isResettingChat}
          showBackButton={showBackButton}
          onBack={onBack}
        />

        {/* Messages - add padding when keyboard is open so messages don't hide behind fixed input */}
        <MessageList
          messages={messages || []}
          loading={messagesLoading}
          contactName={contactName}
          contactPhone={contactPhone}
          contactAvatarUrl={contactAvatar || contactData?.urlAvatar}
          embedded={embedded}
          hoveredMessageId={hoveredMessageId}
          onHover={setHoveredMessageId}
          isInitialLoad={isInitialLoad && !hasInitializedScroll}
          onEditPendingMessage={handleEditPendingMessage}
          onSendPendingMessage={handleSendPendingMessage}
          onDiscardPendingMessage={handleDiscardPendingMessage}
          onRerunPendingMessage={handleRerunPendingMessage}
          isRerunning={chatActions.isRerunningAssistant}
          hasNextPage={hasNextPage}
          fetchNextPage={fetchNextPage}
          isFetchingNextPage={isFetchingNextPage}
          keyboardPadding={isMobileKeyboardOpen ? 80 : 0}
          isUserAdmin={isAdmin(user)}
        />

        {/* Input container - fixed at bottom when keyboard is open on mobile */}
        <div 
          className={`bg-white ${isMobileKeyboardOpen ? 'fixed left-0 right-0 z-50' : ''}`}
          style={isMobileKeyboardOpen ? { 
            bottom: 0,
            boxShadow: '0 -2px 10px rgba(0, 0, 0, 0.1)',
          } : undefined}
        >
          {/* File Preview Areas */}
          <FilePreview
            file={selectedMediaFile}
            type="media"
            preview={mediaPreview}
            videoThumbnail={videoThumbnail}
            onClear={clearSelectedMediaFile}
            embedded={embedded}
            isFading={isMediaPreviewFading}
            videoSizeError={videoSizeError}
          />
          
          <FilePreview
            file={selectedFile}
            type="document"
            onClear={clearSelectedFile}
            embedded={embedded}
            isFading={isFilePreviewFading}
          />

          {/* Input area */}
          <InputArea
            message={message}
            onChange={setMessage}
            onSend={handleSendMessage}
            onSelectFile={(file) => handleFileSelect({ target: { files: [file] } } as any)}
            onSelectMedia={(file) => handlePhotoSelect({ target: { files: [file] } } as any)}
            disabled={isLoading || isSendingText || isSendingMedia || isSendingFile}
            embedded={embedded}
            hasSelectedFile={!!(selectedFile || selectedMediaFile)}
            isEmojiPickerOpen={isEmojiPickerOpen}
            onEmojiPickerToggle={setIsEmojiPickerOpen}
          />
        </div>
      </div>
      
      {/* Hidden file inputs */}
      <input
        type="file"
        ref={fileInputRef}
        onChange={handleFileSelect}
        accept=".pdf,.doc,.docx,.xls,.xlsx"
        className="hidden"
      />
      <input
        type="file"
        ref={photoInputRef}
        onChange={handlePhotoSelect}
        accept="image/*,video/*"
        className="hidden"
      />
    </div>
  );
};

export default MessagingInterface;