"use client";

import { useState, useRef, useEffect } from 'react';
import { Button } from './ui/button';
import { Paperclip, Send, Mic, X, Smile } from 'lucide-react';
import { CSSTransition } from 'react-transition-group';
import { VoiceRecorder } from './voice-recorder';
import type { ReplyTo, Message, Group, UserProfile } from '@/lib/types';
import { useSettings } from '@/contexts/settings-context';
import { useAuth } from '@/contexts/auth-context';
import { useChatUtils } from '@/contexts/chat-utils-context';
import { useAppContext } from '@/contexts/app-context';
import { Skeleton } from './ui/skeleton';

// Helper function to extract plain text and emoji data from the contentEditable div
const getMessageFromDiv = (div: HTMLDivElement): string => {
    let message = '';
    div.childNodes.forEach(node => {
        if (node.nodeType === Node.TEXT_NODE) {
            message += node.textContent;
        } else if (node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).tagName === 'IMG') {
            const imgElement = node as HTMLImageElement;
            // Use a specific character or sequence to represent the emoji,
            // which can be parsed on the receiving end.
            // Here, we use the 'alt' attribute which should contain the native emoji character.
            message += imgElement.alt;
        }
    });
    return message;
};

interface MessageInputProps {
    chatId: string | null;
    disabled?: boolean;
    lastMessage: Message | null;
    isGroupChat?: boolean;
    currentGroup?: Group;
    onGetSuggestedReplies: (message: Message) => Promise<string[]>;
    sendTextMessage: (text: string, replyTo?: ReplyTo | null) => void;
    onSelectMedia: (file: File) => void;
    onSendAudio: (data: { file: File, duration: number }) => void;
    editorRef: React.RefObject<HTMLDivElement>;
    onToggleEmojiPicker: () => void;
    isEmojiPickerOpen: boolean;
}

const QuotedMessagePreview = ({ replyTo, onCancel }: { replyTo: ReplyTo | null, onCancel: () => void }) => {
    const nodeRef = useRef(null);
    return (
        <CSSTransition nodeRef={nodeRef} in={!!replyTo} timeout={200} classNames="reply-bar" unmountOnExit>
            <div ref={nodeRef} className="bg-muted/70 px-4 pt-2 pb-1 border-b">
                <div className="bg-background/50 rounded-lg p-2 flex justify-between items-center border-l-4 border-primary">
                    {replyTo && (
                        <>
                            <div>
                                <p className="font-bold text-primary text-sm">{replyTo.displayName}</p>
                                <p className="text-sm text-muted-foreground truncate quoted-message-content">
                                    {replyTo.text || (replyTo.imageKey ? 'Image' : replyTo.videoKey ? 'Video' : 'Voice Message')}
                                </p>
                            </div>
                            <Button variant="ghost" size="icon" className="h-7 w-7" onClick={onCancel}>
                                <X className="h-4 w-4" />
                            </Button>
                        </>
                    )}
                </div>
            </div>
        </CSSTransition>
    );
};

const PrivateReplyPreview = ({ privateReplyTo, onCancel }: { privateReplyTo: UserProfile | null, onCancel: () => void }) => {
    const nodeRef = useRef(null);
    return (
        <CSSTransition nodeRef={nodeRef} in={!!privateReplyTo} timeout={200} classNames="reply-bar" unmountOnExit>
            <div ref={nodeRef} className="bg-primary/10 px-4 pt-2 pb-1 border-b border-primary/20">
                <div className="rounded-lg p-2 flex justify-between items-center">
                    {privateReplyTo && (
                        <>
                            <div className="flex items-center gap-2">
                                {/* <Lock className="h-4 w-4 text-primary" /> */}
                                <div>
                                    <p className="font-bold text-primary text-sm">Private message to {privateReplyTo.displayName}</p>
                                </div>
                            </div>
                            <Button variant="ghost" size="icon" className="h-7 w-7 text-primary" onClick={onCancel}>
                                <X className="h-4 w-4" />
                            </Button>
                        </>
                    )}
                </div>
            </div>
        </CSSTransition>
    );
};

export function MessageInput({ 
    sendTextMessage,
    onSelectMedia,
    onSendAudio,
    chatId,
    disabled,
    lastMessage,
    onGetSuggestedReplies,
    isGroupChat,
    currentGroup,
    editorRef,
    onToggleEmojiPicker,
    isEmojiPickerOpen,
}: MessageInputProps) {
    const { currentUser } = useAuth();
    const { setUserTyping } = useChatUtils();
    const { replyTo, setReplyTo, privateReplyTo, setPrivateReplyTo } = useAppContext();
    const { playSound, t } = useSettings();
    const [isRecording, setIsRecording] = useState(false);
    const [hasText, setHasText] = useState(false);
    const [suggestedReplies, setSuggestedReplies] = useState<string[]>([]);
    const [showSuggestions, setShowSuggestions] = useState(false);
    const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);

    const handleSend = () => {
        if (!editorRef.current) return;
        const message = getMessageFromDiv(editorRef.current);
        
        if (message.trim()) {
            playSound('send');
            sendTextMessage(message, replyTo);
            editorRef.current.innerHTML = '';
            setReplyTo(null);
            setHasText(false);
        }
    };
    
    useEffect(() => {
        const fetchSuggestions = async () => {
            if (lastMessage && lastMessage.sender !== currentUser?.uid && lastMessage.text) {
                setShowSuggestions(true);
                setSuggestedReplies([]); // Clear old suggestions immediately
                const replies = await onGetSuggestedReplies(lastMessage);
                setSuggestedReplies(replies);
            } else {
                setShowSuggestions(false);
                setSuggestedReplies([]);
            }
        };

        // Only fetch suggestions if the last message changes
        if (lastMessage?.id) {
            fetchSuggestions();
        }
    }, [lastMessage?.id, lastMessage?.sender, lastMessage?.text, currentUser?.uid, onGetSuggestedReplies]);

    const handleInputChange = (e: React.FormEvent<HTMLDivElement>) => {
        if (chatId) {
            if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current);
            else setUserTyping(chatId, true);

            typingTimeoutRef.current = setTimeout(() => {
                setUserTyping(chatId, false);
                typingTimeoutRef.current = null;
            }, 2000);
        }
        setHasText(!!e.currentTarget.textContent?.trim() || e.currentTarget.getElementsByTagName('img').length > 0);
    };
    
    const handleSendSuggestion = (reply: string) => {
        sendTextMessage(reply, null);
        setShowSuggestions(false);
    }

    const handleKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {
        if (event.key === 'Enter' && !event.shiftKey) {
            event.preventDefault();
            handleSend();
        }
    };
    
    const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (file) {
            onSelectMedia(file);
        }
        // Reset the input value to allow selecting the same file again
        e.target.value = '';
    };

    const handleFocus = () => {
        if (isEmojiPickerOpen) {
            editorRef.current?.blur();
        }
    };

    if (disabled) {
        return (
            <div className="p-4 border-t text-center text-sm text-muted-foreground">
                {t('messagingDisabled')}
            </div>
        );
    }
    
    const sendingMode = currentGroup?.info?.settings?.sendingMode || 'everyone';
    const isMuted = isGroupChat && currentGroup?.info.mutedMembers?.[currentUser?.uid || ''];
    const canSend = !isGroupChat || (
        (sendingMode === 'everyone' && !isMuted) ||
        (sendingMode === 'admins' && currentGroup?.admins[currentUser?.uid || '']) ||
        (sendingMode === 'owner' && currentGroup?.info.createdBy === currentUser?.uid)
    );
    
     if (!canSend) {
        return (
            <div className="p-4 border-t text-center text-sm text-muted-foreground">
                <p>{isMuted ? t('youAreMuted') : t('adminsCanSend')}</p>
            </div>
        );
    }

    if (isRecording) {
        return <VoiceRecorder onCancel={() => setIsRecording(false)} onSend={onSendAudio} />;
    }

    return (
        <div className="flex flex-col border-t bg-background/80 backdrop-blur-sm">
            <PrivateReplyPreview privateReplyTo={privateReplyTo} onCancel={() => setPrivateReplyTo(null)} />
            <QuotedMessagePreview replyTo={replyTo} onCancel={() => setReplyTo(null)} />
            
             {showSuggestions && (
                <div className="p-2 border-b">
                    <div className="flex gap-2 overflow-x-auto pb-2">
                        {suggestedReplies.length > 0 ? (
                            suggestedReplies.map((reply, i) => (
                                <Button key={i} variant="outline" size="sm" className="flex-shrink-0" onClick={() => handleSendSuggestion(reply)}>
                                    {reply}
                                </Button>
                            ))
                        ) : (
                            Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className="h-9 w-24 rounded-md" />)
                        )}
                         <Button variant="ghost" size="icon" className="h-9 w-9 flex-shrink-0" onClick={() => setShowSuggestions(false)}><X className="h-4 w-4"/></Button>
                    </div>
                </div>
            )}
            
            <div className="flex items-start gap-2 p-2 md:p-4">
                <input type="file" id="file-upload" className="hidden" onChange={handleFileSelect} accept="image/*,video/*" />
                <Button asChild variant="ghost" size="icon" title="Attach file">
                    <label htmlFor="file-upload" className="cursor-pointer">
                        <Paperclip />
                        <span className="sr-only">Attach file</span>
                    </label>
                </Button>
                
                <Button variant="ghost" size="icon" title="Add emoji" onClick={onToggleEmojiPicker}>
                    <Smile />
                    <span className="sr-only">Add emoji</span>
                </Button>

                <div className="rich-input-container flex-1">
                    <div
                        ref={editorRef}
                        contentEditable="true"
                        onInput={handleInputChange}
                        onKeyDown={handleKeyPress}
                        onFocus={handleFocus}
                        data-placeholder={t('typeMessage')}
                        className="rich-input-editor"
                    />
                </div>
                
                {hasText ? (
                    <Button onClick={handleSend} size="icon" className="rounded-full h-10 w-10 flex-shrink-0" title="Send message">
                        <Send />
                        <span className="sr-only">Send</span>
                    </Button>
                ) : (
                    <Button onClick={() => { playSound('touch'); setIsRecording(true); }} size="icon" className="rounded-full h-10 w-10 flex-shrink-0" title="Record voice message">
                        <Mic />
                         <span className="sr-only">Record</span>
                    </Button>
                )}
            </div>
        </div>
    );
}
    