import React, {
  useState,
  useCallback,
  useRef,
  useEffect,
  lazy,
  Suspense,
} from 'react';
import {
  Send,
  Smile,
  Paperclip,
  X,
  Image as ImageIcon,
  File,
  Mic,
} from 'lucide-react';
import { useChat } from '../hooks/useChat';
import { useChatStore } from '../store/chatStore';
import { Theme } from 'emoji-picker-react';
import { useDropzone } from 'react-dropzone';
import { apiClient } from '@/services/api/client';
import { MessageAttachment } from '../types';
import { LoadingSpinner } from '@/components/ui/loading-spinner';
import { logger } from '@/utils/logger';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { useIsRateLimited } from '@/hooks/useIsRateLimited';

// Lazy load
const EmojiPicker = lazy(() =>
  import('emoji-picker-react').then((module) => ({ default: module.default })),
);

export const ChatInput: React.FC = () => {
  const [message, setMessage] = useState('');
  const [attachments, setAttachments] = useState<MessageAttachment[]>([]);
  const [isUploading, setIsUploading] = useState(false);
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  const { sendMessage, setTyping } = useChat();
  const { currentConversationId } = useChatStore();
  const isRateLimited = useIsRateLimited();
  const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if ((message.trim() || attachments.length > 0) && currentConversationId) {
      sendMessage(message, attachments.length > 0 ? attachments : undefined);
      setMessage('');
      setAttachments([]);

      if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current);
      setTyping(false);
    }
  };

  const fileInputRef = useRef<HTMLInputElement>(null);

  const onDrop = useCallback(async (acceptedFiles: File[]) => {
    setIsUploading(true);
    try {
      const uploadPromises = acceptedFiles.map(async (file) => {
        const formData = new FormData();
        formData.append('file', file);
        const response = await apiClient.post('/uploads', formData, {
          headers: { 'Content-Type': 'multipart/form-data' },
        });
        const data = response.data;
        return {
          file_name: file.name,
          file_type: file.type,
          file_url: data.url,
          file_size: file.size,
        } as MessageAttachment;
      });

      const newAttachments = await Promise.all(uploadPromises);
      setAttachments((prev) => [...prev, ...newAttachments]);
    } catch (error) {
      logger.error('Failed to upload files', {
        error: error instanceof Error ? error.message : String(error),
      });
    } finally {
      setIsUploading(false);
    }
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    noClick: true,
  });

  const handleEmojiClick = (emojiData: { emoji: string }) => {
    setMessage((prev) => prev + emojiData.emoji);
    setShowEmojiPicker(false);
  };

  const removeAttachment = (index: number) => {
    setAttachments((prev) => prev.filter((_, i) => i !== index));
  };

  useEffect(() => {
    if (message.length > 0) {
      setTyping(true);
      if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current);
      typingTimeoutRef.current = setTimeout(() => {
        setTyping(false);
      }, 3000);
    } else {
      setTyping(false);
    }
  }, [message, setTyping]);

  return (
    <div {...getRootProps()} className="relative">
      <input {...getInputProps()} ref={fileInputRef} className="hidden" />

      {/* Upload Overlay */}
      {isDragActive && (
        <div className="absolute bottom-full left-0 right-0 h-48 z-50 bg-kodo-cyan/10 backdrop-blur-md flex items-center justify-center border-t-2 border-kodo-cyan border-dashed rounded-t-2xl animate-fadeIn">
          <div className="text-center">
            <div className="w-12 h-12 rounded-full bg-kodo-cyan/20 flex items-center justify-center mx-auto mb-2 animate-bounce">
              <Paperclip className="w-6 h-6 text-kodo-cyan" />
            </div>
            <p className="text-kodo-cyan font-mono uppercase tracking-widest text-sm">
              Initiate Data Transfer
            </p>
          </div>
        </div>
      )}

      {/* Attachments Preview */}
      {attachments.length > 0 && (
        <div className="absolute bottom-full left-0 right-0 p-3 bg-kodo-void/90 backdrop-blur-xl border-t border-white/10 flex gap-2 overflow-x-auto">
          {attachments.map((att, i) => (
            <div
              key={i}
              className="relative group flex items-center gap-2 p-2 bg-white/5 rounded-lg border border-white/10 text-xs text-white min-w-[150px]"
            >
              {att.file_type.startsWith('image') ? (
                <ImageIcon size={14} className="text-kodo-cyan" />
              ) : (
                <File size={14} className="text-kodo-secondary" />
              )}
              <span className="truncate flex-1">{att.file_name}</span>
              <button
                onClick={() => removeAttachment(i)}
                className="p-1 hover:bg-white/10 rounded-full text-kodo-red opacity-0 group-hover:opacity-100 transition-opacity"
              >
                <X size={12} />
              </button>
            </div>
          ))}
        </div>
      )}

      <form onSubmit={handleSubmit} className="flex items-center gap-2">
        <div className="flex gap-1">
          <Button
            type="button"
            variant="ghost"
            size="icon"
            className="text-kodo-secondary hover:text-kodo-cyan hover:bg-white/5"
            onClick={() => fileInputRef.current?.click()}
          >
            <Paperclip size={20} />
          </Button>

          <div className="relative">
            <Button
              type="button"
              variant="ghost"
              size="icon"
              className={cn(
                'text-kodo-secondary hover:text-kodo-cyan hover:bg-white/5',
                showEmojiPicker && 'text-kodo-cyan bg-white/5',
              )}
              onClick={() => setShowEmojiPicker(!showEmojiPicker)}
            >
              <Smile size={20} />
            </Button>

            {showEmojiPicker && (
              <div className="absolute bottom-full left-0 mb-4 z-50 animate-scaleIn origin-bottom-left">
                <div
                  className="fixed inset-0"
                  onClick={() => setShowEmojiPicker(false)}
                />
                <div className="relative shadow-2xl rounded-xl overflow-hidden border border-white/10">
                  <Suspense
                    fallback={
                      <div className="w-[350px] h-[450px] bg-kodo-ink flex items-center justify-center">
                        <LoadingSpinner />
                      </div>
                    }
                  >
                    <EmojiPicker
                      onEmojiClick={handleEmojiClick}
                      theme={Theme.DARK}
                      lazyLoadEmojis={true}
                      width={350}
                      height={450}
                    />
                  </Suspense>
                </div>
              </div>
            )}
          </div>
        </div>

        <div className="flex-1 relative">
          <input
            type="text"
            value={message}
            onChange={(e) => setMessage(e.target.value)}
            placeholder="Broadcast message..."
            className="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-2.5 text-white placeholder:text-kodo-secondary/50 focus:outline-none focus:border-kodo-cyan/50 focus:ring-1 focus:ring-kodo-cyan/50 transition-all font-mono text-sm"
            disabled={!currentConversationId || isUploading}
          />
          {message.length === 0 && !isUploading && (
            <div className="absolute right-2 top-1/2 -translate-y-1/2">
              <Mic className="w-4 h-4 text-kodo-secondary/30 hover:text-kodo-cyan cursor-pointer transition-colors" />
            </div>
          )}
        </div>

        <Button
          type="submit"
          variant="default"
          size="icon"
          className={cn(
            'rounded-xl transition-all duration-300',
            message.trim() || attachments.length > 0
              ? 'bg-kodo-cyan text-kodo-void hover:bg-kodo-cyan-dim shadow-neon-cyan'
              : 'bg-white/5 text-kodo-secondary hover:bg-white/10',
          )}
          disabled={
            !currentConversationId ||
            (!message.trim() && attachments.length === 0) ||
            isUploading ||
            isRateLimited
          }
        >
          {isUploading ? (
            <div className="w-5 h-5 border-2 border-kodo-void/30 border-t-kodo-void rounded-full animate-spin" />
          ) : (
            <Send
              size={18}
              className={cn(message.trim() ? 'translate-x-0.5' : '')}
            />
          )}
        </Button>
      </form>
    </div>
  );
};
