import React, { useState, useRef, useCallback } from 'react';
import { Send, Paperclip, Smile, X, Image, Music, FileText } from 'lucide-react';
import { useWebSocket } from '../../hooks/useWebSocket';
import { useFileUpload } from '../../hooks/useFileUpload';
import { validateFile, formatFileSize } from '../../utils/fileValidation';

const MessageInput = ({ conversation, onSendMessage, onTypingStart, onTypingStop }) => {
  const [message, setMessage] = useState('');
  const [isTyping, setIsTyping] = useState(false);
  const [fileUpload, setFileUpload] = useState(null);
  const fileInputRef = useRef();
  const textareaRef = useRef();
  
  const { sendMessage } = useWebSocket();
  const { uploadFile, uploading, progress, error: uploadError, reset: resetUpload } = useFileUpload();

  const typingTimeoutRef = useRef();

  const handleSubmit = async (e) => {
    e.preventDefault();
    
    if (!message.trim() && !fileUpload) return;

    // Reset typing
    stopTyping();

    if (fileUpload) {
      // Send file message
      await sendFileMessage();
    } else {
      // Send text message
      sendTextMessage();
    }

    setMessage('');
    setFileUpload(null);
    resetUpload();
  };

  const sendTextMessage = () => {
    if (!message.trim()) return;

    const messageData = {
      conversationId: conversation._id,
      content: message.trim(),
      type: 'text'
    };

    sendMessage('message:send', messageData);
    onSendMessage({
      ...messageData,
      _id: `temp-${Date.now()}`,
      sender: { _id: 'current-user' },
      createdAt: new Date(),
      status: 'sending'
    });
  };

  const sendFileMessage = async () => {
    if (!fileUpload) return;

    try {
      const response = await uploadFile(fileUpload.file);
      
      const messageData = {
        conversationId: conversation._id,
        content: message.trim() || `Sent ${getFileTypeDescription(fileUpload.file.type)}`,
        type: getMessageType(fileUpload.file.type),
        attachment: {
          url: response.file.url,
          filename: response.file.fileName,
          originalName: fileUpload.file.name,
          mimeType: fileUpload.file.type,
          size: fileUpload.file.size,
          thumbnail: response.file.thumbnail
        }
      };

      sendMessage('message:send', messageData);
      onSendMessage({
        ...messageData,
        _id: `temp-${Date.now()}`,
        sender: { _id: 'current-user' },
        createdAt: new Date(),
        status: 'sending'
      });
    } catch (error) {
      console.error('Failed to send file message:', error);
    }
  };

  const handleInputChange = (e) => {
    setMessage(e.target.value);
    
    if (!isTyping) {
      startTyping();
    }
    
    // Reset typing timeout
    clearTimeout(typingTimeoutRef.current);
    typingTimeoutRef.current = setTimeout(stopTyping, 1000);
  };

  const startTyping = () => {
    if (!isTyping) {
      setIsTyping(true);
      sendMessage('typing:start', { conversationId: conversation._id });
    }
  };

  const stopTyping = () => {
    if (isTyping) {
      setIsTyping(false);
      sendMessage('typing:stop', { conversationId: conversation._id });
    }
  };

  const handleFileSelect = async (e) => {
    const file = e.target.files[0];
    if (!file) return;

    try {
      validateFile(file);
      
      setFileUpload({
        file,
        name: file.name,
        size: file.size,
        type: file.type
      });
      
      // Reset file input
      fileInputRef.current.value = '';
    } catch (error) {
      alert(error.message);
    }
  };

  const removeFile = () => {
    setFileUpload(null);
    resetUpload();
  };

  const getFileTypeDescription = (mimeType) => {
    if (mimeType.startsWith('image/')) return 'an image';
    if (mimeType.startsWith('audio/')) return 'an audio file';
    if (mimeType === 'application/pdf') return 'a PDF';
    if (mimeType.startsWith('text/')) return 'a text file';
    return 'a file';
  };

  const getMessageType = (mimeType) => {
    if (mimeType.startsWith('image/')) return 'image';
    if (mimeType.startsWith('audio/')) return 'audio';
    return 'file';
  };

  const getFileIcon = (mimeType) => {
    if (mimeType.startsWith('image/')) return <Image className="w-4 h-4" />;
    if (mimeType.startsWith('audio/')) return <Music className="w-4 h-4" />;
    return <FileText className="w-4 h-4" />;
  };

  const handleKeyPress = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSubmit(e);
    }
  };

  const adjustTextareaHeight = () => {
    const textarea = textareaRef.current;
    if (textarea) {
      textarea.style.height = 'auto';
      textarea.style.height = Math.min(textarea.scrollHeight, 120) + 'px';
    }
  };

  return (
    <div className="border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-4">
      {/* File Upload Preview */}
      {fileUpload && (
        <div className="mb-4 p-3 bg-gray-50 dark:bg-gray-700 rounded-lg border border-gray-200 dark:border-gray-600">
          <div className="flex items-center justify-between mb-2">
            <div className="flex items-center space-x-2">
              {getFileIcon(fileUpload.type)}
              <span className="text-sm font-medium text-gray-900 dark:text-white truncate">
                {fileUpload.name}
              </span>
            </div>
            <button
              onClick={removeFile}
              className="p-1 hover:bg-gray-200 dark:hover:bg-gray-600 rounded transition-colors"
            >
              <X className="w-4 h-4 text-gray-500" />
            </button>
          </div>
          
          <div className="flex items-center justify-between text-sm text-gray-500 dark:text-gray-400">
            <span>{formatFileSize(fileUpload.size)}</span>
            
            {uploading && (
              <div className="flex items-center space-x-2">
                <div className="w-20 bg-gray-200 dark:bg-gray-600 rounded-full h-2">
                  <div 
                    className="bg-primary-500 h-2 rounded-full transition-all duration-300"
                    style={{ width: `${progress}%` }}
                  ></div>
                </div>
                <span>{progress}%</span>
              </div>
            )}
          </div>

          {uploadError && (
            <p className="text-sm text-red-600 dark:text-red-400 mt-1">{uploadError}</p>
          )}
        </div>
      )}

      {/* Hidden File Input */}
      <input
        type="file"
        ref={fileInputRef}
        onChange={handleFileSelect}
        accept="image/*,audio/*,.pdf,.txt,.md"
        className="hidden"
      />

      <form onSubmit={handleSubmit} className="flex items-end space-x-2">
        {/* File Attachment Button */}
        <button
          type="button"
          onClick={() => fileInputRef.current?.click()}
          disabled={uploading}
          className="p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors disabled:opacity-50"
          title="Attach file"
        >
          <Paperclip size={20} />
        </button>

        {/* Message Input */}
        <div className="flex-1 relative">
          <textarea
            ref={textareaRef}
            value={message}
            onChange={(e) => {
              handleInputChange(e);
              adjustTextareaHeight();
            }}
            onKeyPress={handleKeyPress}
            placeholder="Type a message..."
            className="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-2xl focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 resize-none max-h-32"
            rows={1}
            disabled={uploading}
          />
        </div>

        {/* Send Button */}
        <button
          type="submit"
          disabled={(!message.trim() && !fileUpload) || uploading}
          className="p-3 bg-primary-500 text-white rounded-full hover:bg-primary-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex-shrink-0"
          title="Send message"
        >
          <Send size={20} />
        </button>
      </form>

      {/* Typing Indicator */}
      {isTyping && (
        <div className="text-xs text-gray-500 dark:text-gray-400 mt-2">
          Typing...
        </div>
      )}
    </div>
  );
};

export default MessageInput;