'use client';

import Image from 'next/image';
import { useState, useRef, useEffect, useCallback } from 'react';
import data from '@emoji-mart/data';
import Picker from '@emoji-mart/react';
import { GiphyFetch } from '@giphy/js-fetch-api';
import { Grid } from '@giphy/react-components';

const gf = new GiphyFetch(process.env.NEXT_PUBLIC_GIPHY_API_KEY || '');


interface AttachedFile {
  file: File;
  preview?: string; // Object URL for image preview
  messageType: 'IMAGE' | 'FILE';
}

interface MessageInputProps {
  onSend?: (message: string) => void;
  onSendGif?: (gifUrl: string) => void;
  onSendFile?: (file: File, messageType: 'IMAGE' | 'FILE') => void;
  onTypingStart?: () => void;
  onTypingStop?: () => void;
  isUploading?: boolean;
}

export function MessageInput({ onSend, onSendGif, onSendFile, onTypingStart, onTypingStop, isUploading }: MessageInputProps) {
  const [message, setMessage] = useState('');
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  const [showGifPicker, setShowGifPicker] = useState(false);
  const [gifSearchQuery, setGifSearchQuery] = useState('');
  const [attachedFile, setAttachedFile] = useState<AttachedFile | null>(null);
  const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const isTypingRef = useRef(false);
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const emojiPickerRef = useRef<HTMLDivElement>(null);
  const gifPickerRef = useRef<HTMLDivElement>(null);
  const emojiButtonRef = useRef<HTMLButtonElement>(null);
  const gifButtonRef = useRef<HTMLButtonElement>(null);
  const imageInputRef = useRef<HTMLInputElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Handle typing indicator
  const handleTyping = useCallback(() => {
    if (!isTypingRef.current && onTypingStart) {
      isTypingRef.current = true;
      onTypingStart();
    }

    if (typingTimeoutRef.current) {
      clearTimeout(typingTimeoutRef.current);
    }

    typingTimeoutRef.current = setTimeout(() => {
      if (isTypingRef.current && onTypingStop) {
        isTypingRef.current = false;
        onTypingStop();
      }
    }, 2000);
  }, [onTypingStart, onTypingStop]);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      if (typingTimeoutRef.current) {
        clearTimeout(typingTimeoutRef.current);
      }
      if (isTypingRef.current && onTypingStop) {
        onTypingStop();
      }
    };
  }, [onTypingStop]);

  // Close pickers on click outside
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (
        showEmojiPicker &&
        emojiPickerRef.current &&
        !emojiPickerRef.current.contains(e.target as Node) &&
        emojiButtonRef.current &&
        !emojiButtonRef.current.contains(e.target as Node)
      ) {
        setShowEmojiPicker(false);
      }
      if (
        showGifPicker &&
        gifPickerRef.current &&
        !gifPickerRef.current.contains(e.target as Node) &&
        gifButtonRef.current &&
        !gifButtonRef.current.contains(e.target as Node)
      ) {
        setShowGifPicker(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [showEmojiPicker, showGifPicker]);

  // Clean up object URL on unmount or when file changes
  useEffect(() => {
    return () => {
      if (attachedFile?.preview) {
        URL.revokeObjectURL(attachedFile.preview);
      }
    };
  }, [attachedFile]);

  const handleImageSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const preview = URL.createObjectURL(file);
    setAttachedFile({ file, preview, messageType: 'IMAGE' });
    // Reset input so same file can be selected again
    e.target.value = '';
  };

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setAttachedFile({ file, messageType: 'FILE' });
    e.target.value = '';
  };

  const removeAttachment = () => {
    if (attachedFile?.preview) {
      URL.revokeObjectURL(attachedFile.preview);
    }
    setAttachedFile(null);
  };

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

  const handleSend = () => {
    // Send attached file
    if (attachedFile && onSendFile) {
      if (typingTimeoutRef.current) {
        clearTimeout(typingTimeoutRef.current);
      }
      if (isTypingRef.current && onTypingStop) {
        isTypingRef.current = false;
        onTypingStop();
      }

      onSendFile(attachedFile.file, attachedFile.messageType);
      removeAttachment();
      setMessage('');
      return;
    }

    // Send text message
    if (message.trim() && onSend) {
      if (typingTimeoutRef.current) {
        clearTimeout(typingTimeoutRef.current);
      }
      if (isTypingRef.current && onTypingStop) {
        isTypingRef.current = false;
        onTypingStop();
      }

      onSend(message.trim());
      setMessage('');
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      if (!isUploading) handleSend();
    }
  };

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

  const handleEmojiSelect = (emoji: { native: string }) => {
    const textarea = textareaRef.current;
    if (textarea) {
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const newMessage = message.slice(0, start) + emoji.native + message.slice(end);
      setMessage(newMessage);
      // Restore cursor position after emoji
      setTimeout(() => {
        textarea.selectionStart = textarea.selectionEnd = start + emoji.native.length;
        textarea.focus();
      }, 0);
    } else {
      setMessage((prev) => prev + emoji.native);
    }
  };

  const handleGifSelect = (gif: { images: { original: { url: string } } }, e: React.SyntheticEvent) => {
    e.preventDefault();
    const gifUrl = gif.images.original.url;
    if (onSendGif) {
      onSendGif(gifUrl);
    }
    setShowGifPicker(false);
    setGifSearchQuery('');
  };

  const toggleEmojiPicker = () => {
    setShowEmojiPicker((prev) => !prev);
    setShowGifPicker(false);
  };

  const toggleGifPicker = () => {
    setShowGifPicker((prev) => !prev);
    setShowEmojiPicker(false);
  };

  const fetchGifs = useCallback(
    (offset: number) => {
      if (gifSearchQuery.trim()) {
        return gf.search(gifSearchQuery, { offset, limit: 10 });
      }
      return gf.trending({ offset, limit: 10 });
    },
    [gifSearchQuery]
  );

  const canSend = message.trim() || attachedFile;

  return (
    <div className="border border-[#00293d]/10 rounded-[20px] bg-white p-4">
      {/* Hidden file inputs */}
      <input
        ref={imageInputRef}
        type="file"
        accept="image/jpeg,image/png,image/webp,image/gif"
        onChange={handleImageSelect}
        className="hidden"
      />
      <input
        ref={fileInputRef}
        type="file"
        accept=".pdf,.doc,.docx,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        onChange={handleFileSelect}
        className="hidden"
      />

      {/* Attachment preview area */}
      {attachedFile && (
        <div className="border border-[#00293d]/10 rounded-[15px] p-3 mb-3 bg-[#00293d]/[0.02]">
          <div className="flex items-center gap-3">
            {attachedFile.messageType === 'IMAGE' && attachedFile.preview ? (
              <img
                src={attachedFile.preview}
                alt="Preview"
                className="w-[80px] h-[80px] object-cover rounded-[10px]"
              />
            ) : (
              <div className="w-[50px] h-[50px] bg-[#e58625]/10 rounded-[10px] flex items-center justify-center flex-shrink-0">
                <Image
                  src="/assets/icons/attachment-icon.svg"
                  alt="File"
                  width={22}
                  height={12}
                />
              </div>
            )}
            <div className="flex-1 min-w-0">
              <p className="font-serif font-normal text-[14px] leading-[19px] text-[#00293D] truncate">
                {attachedFile.file.name}
              </p>
              <p className="font-serif font-normal text-[12px] leading-[16px] text-[#00293D]/50">
                {formatFileSize(attachedFile.file.size)}
              </p>
            </div>
            <button
              onClick={removeAttachment}
              className="p-1 hover:bg-gray-100 rounded-full transition-colors cursor-pointer flex-shrink-0"
              title="Remove attachment"
            >
              <Image
                src="/assets/icons/close-icon.svg"
                alt="Remove"
                width={20}
                height={20}
                className="opacity-50"
              />
            </button>
          </div>
        </div>
      )}

      {/* Text input area */}
      <div className="border border-[#00293d]/10 rounded-[20px] p-4 mb-3">
        <textarea
          ref={textareaRef}
          value={message}
          onChange={handleChange}
          onKeyDown={handleKeyDown}
          placeholder="Write a Message........"
          className="w-full min-h-[120px] resize-none font-serif font-normal text-[14px] leading-[19px] text-[#00293D] placeholder-[#00293D]/50 focus:outline-none"
        />
      </div>

      {/* Action bar */}
      <div className="flex items-center justify-between">
        {/* Attachment buttons */}
        <div className="flex items-center gap-3">
          <button
            onClick={() => imageInputRef.current?.click()}
            className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors cursor-pointer"
            title="Attach image"
          >
            <Image
              src="/assets/icons/gallery-icon.svg"
              alt="Add image"
              width={24}
              height={24}
            />
          </button>
          <button
            onClick={() => fileInputRef.current?.click()}
            className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors cursor-pointer"
            title="Attach file"
          >
            <Image
              src="/assets/icons/chain-icon.svg"
              alt="Attach file"
              width={24}
              height={24}
            />
          </button>

          {/* GIF button with picker */}
          <div className="relative">
            <button
              ref={gifButtonRef}
              onClick={toggleGifPicker}
              className={`p-1.5 rounded-lg transition-colors cursor-pointer ${showGifPicker ? 'bg-[#e58625]/20' : 'hover:bg-gray-100'}`}
            >
              <Image
                src="/assets/icons/gif-icon.svg"
                alt="Add GIF"
                width={24}
                height={24}
              />
            </button>
            {showGifPicker && (
              <div
                ref={gifPickerRef}
                className="absolute bottom-full left-0 mb-2 z-50 bg-white border border-[#00293d]/10 rounded-[15px] shadow-lg overflow-hidden"
                style={{ width: '360px', height: '420px' }}
              >
                <div className="p-3 border-b border-[#00293d]/10">
                  <input
                    type="text"
                    value={gifSearchQuery}
                    onChange={(e) => setGifSearchQuery(e.target.value)}
                    placeholder="Search GIFs..."
                    className="w-full px-3 py-2 border border-[#00293d]/10 rounded-[10px] font-serif text-[14px] text-[#00293D] placeholder-[#00293D]/50 focus:outline-none focus:border-[#e58625]"
                    autoFocus
                  />
                </div>
                <div className="overflow-y-auto" style={{ height: 'calc(100% - 56px)' }}>
                  <Grid
                    key={gifSearchQuery}
                    fetchGifs={fetchGifs}
                    width={356}
                    columns={2}
                    gutter={6}
                    noLink
                    onGifClick={handleGifSelect}
                  />
                </div>
                <div className="absolute bottom-2 right-3 bg-white/80 rounded px-1.5 py-0.5">
                  <span className="font-serif text-[10px] text-[#00293D]/40">Powered by GIPHY</span>
                </div>
              </div>
            )}
          </div>

          {/* Emoji button with picker */}
          <div className="relative">
            <button
              ref={emojiButtonRef}
              onClick={toggleEmojiPicker}
              className={`p-1.5 rounded-lg transition-colors cursor-pointer ${showEmojiPicker ? 'bg-[#e58625]/20' : 'hover:bg-gray-100'}`}
            >
              <Image
                src="/assets/icons/emoji-icon.svg"
                alt="Add emoji"
                width={24}
                height={24}
              />
            </button>
            {showEmojiPicker && (
              <div ref={emojiPickerRef} className="absolute bottom-full left-0 mb-2 z-50">
                <Picker
                  data={data}
                  onEmojiSelect={handleEmojiSelect}
                  theme="light"
                  previewPosition="none"
                  skinTonePosition="search"
                />
              </div>
            )}
          </div>
        </div>

        {/* Send button and more options */}
        <div className="flex items-center gap-2">
          <button
            onClick={handleSend}
            disabled={!canSend || isUploading}
            className={`px-4 py-1.5 font-serif font-normal text-[14px] leading-[19px] rounded-[15px] transition-colors cursor-pointer ${
              canSend && !isUploading
                ? 'bg-[#e58625] text-[#00293d] hover:bg-[#d47720]'
                : 'bg-[#e58625]/50 text-[#00293d]/50 cursor-not-allowed'
            }`}
          >
            {isUploading ? 'Uploading...' : 'Send'}
          </button>
        </div>
      </div>
    </div>
  );
}
