"use client";

import { useState, useEffect, useRef, useMemo, useCallback, useLayoutEffect } from 'react';
import { useAuth } from '@/contexts/auth-context';
import { useGroups } from '@/contexts/groups-context';
import { useSettings } from '@/contexts/settings-context';
import { useChat } from '@/hooks/use-chat';
import { Message, ChatRecipient, User, Group, CallType, ActionPayload } from '@/lib/types';
import { Button } from '@/components/ui/button';
import { ArrowLeft, Ban, Info, MoreVertical, Loader2, MessageCircleX, Phone, Video, FileText, Search, X, Smile } from 'lucide-react';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { MessageInput } from '@/components/message-input';
import { MessageItem } from '@/components/message-item';
import { Skeleton } from '@/components/ui/skeleton';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/components/ui/alert-dialog';
import { MediaPreviewModal } from '@/components/media-preview-modal';
import { GroupInfoPanel } from '@/components/group-info-panel';
import { SendAudioModal } from '@/components/send-audio-modal';
import { useChatUtils } from '@/contexts/chat-utils-context';
import { generateLocalSummary, type LocalSummary } from '@/lib/local-summarizer';
import { useTheme } from 'next-themes';
import { Input } from '@/components/ui/input';
import { cn } from '@/lib/utils';
import { generateSuggestedReplies } from '@/lib/suggested-replies';
import EmojiPicker, { EmojiStyle, Theme as EmojiTheme } from 'emoji-picker-react';


interface ChatWindowProps {
    recipient: ChatRecipient | null;
    onClose: () => void;
    onViewProfile: (user: User) => void;
    onPreviewImage: (imageUrl: string, isViewOnce?: boolean, onViewed?: () => void) => void;
    onAddMembers: (group: Group) => void;
    onStartCall: (peer: User, type: CallType) => void;
    openChangeNameModal: () => void;
    openChangeStatusModal: () => void;
    openChangeBioModal: () => void;
    onOpenSettings: (section?: string) => void;
}

const BlockedBanner = ({ recipient, isBlockedByYou, t }: { recipient: ChatRecipient; isBlockedByYou: boolean, t: (key: any, options?: any) => string }) => (
     <div className="flex flex-col items-center text-center p-4 bg-destructive/10 border-b border-destructive/20">
        <Ban className="w-8 h-8 text-destructive mb-2" />
        <p className="text-sm text-destructive-foreground">
            {isBlockedByYou ? t('blockedBannerYou', { name: recipient.displayName }) : t('blockedBannerOther', { name: recipient.displayName })}
        </p>
    </div>
);


export function ChatWindow({ 
    recipient, 
    onClose, 
    onViewProfile, 
    onPreviewImage, 
    onAddMembers, 
    onStartCall, 
    openChangeBioModal,
    openChangeNameModal,
    openChangeStatusModal,
    onOpenSettings,
}: ChatWindowProps) {
    const { currentUser } = useAuth();
    const { groups } = useGroups();
    const { clearChatHistory, deleteMessage } = useChatUtils();
    const { playSound, t, formatDistanceToNow, addToast, toggleSound, isSoundEnabled, privacySettings, updatePrivacySettings, fontStyle, setFontStyle, dataMode, setDataMode, language } = useSettings();
    const { messages, loading, sendTextMessage, sendMediaMessage, sendVoiceMessage, editMessage, toggleReaction, chatId, typingUsers } = useChat(recipient);
    const { theme, setTheme } = useTheme();

    const messagesEndRef = useRef<HTMLDivElement>(null);
    const chatContainerRef = useRef<HTMLDivElement>(null);
    const editorRef = useRef<HTMLDivElement>(null);
    const lastRange = useRef<Range | null>(null);
    
    const [confirmAction, setConfirmAction] = useState<{ type: 'block' | 'unblock' | 'remove' | 'clear_history' } | null>(null);
    const [messageToDelete, setMessageToDelete] = useState<Message | null>(null);
    const [deletingMessageId, setDeletingMessageId] = useState<string | null>(null);
    const [mediaFile, setMediaFile] = useState<{ file: File, originalSize: number, compressedBlob?: Blob } | null>(null);
    const [audioToSend, setAudioToSend] = useState<{ file: File; duration: number } | null>(null);
    const [isGroupInfoOpen, setGroupInfoOpen] = useState(false);
    const [clientReadyStatus, setClientReadyStatus] = useState<string | null>(null);
    
    const [isSummarizing, setIsSummarizing] = useState(false);
    const [summary, setSummary] = useState<LocalSummary | null>(null);
    
    const [isSearching, setIsSearching] = useState(false);
    const [searchQuery, setSearchQuery] = useState('');
    const [viewedOnceMessages, setViewedOnceMessages] = useState<Set<string>>(new Set());
    const [isEmojiPickerOpen, setIsEmojiPickerOpen] = useState(false);

    
    const currentGroup = useMemo<Group | undefined>(() => {
        if (!recipient?.isGroup) return undefined;
        return groups.find(g => g.id === recipient.uid);
    }, [recipient, groups]);


    const scrollToBottom = useCallback(() => {
        if (messagesEndRef.current) {
            messagesEndRef.current.scrollIntoView({ behavior: "auto" });
        }
    }, []);
    
    useLayoutEffect(() => {
        scrollToBottom();
    }, [messages, typingUsers, chatId, scrollToBottom]);

    useEffect(() => {
        // This event is dispatched from MessageItem when an image loads
        const handleImageLoad = () => scrollToBottom();
        window.addEventListener('imageLoaded', handleImageLoad);
        return () => {
            window.removeEventListener('imageLoaded', handleImageLoad);
        };
    }, [scrollToBottom]);


    // Search logic effect
    useEffect(() => {
        if (isSearching && searchQuery.trim()) {
            setTimeout(() => {
                const firstResult = chatContainerRef.current?.querySelector('mark.search-highlight');
                if (firstResult) {
                    firstResult.scrollIntoView({ block: 'center', behavior: 'smooth' });
                }
            }, 100);
        }
    }, [searchQuery, messages, isSearching]);

    const isBlockedByYou = useMemo(() => {
        if(!recipient || !currentUser?.blockedUsers) return false;
        return !!currentUser?.blockedUsers?.[recipient.uid]
    }, [currentUser, recipient]);

    const isBlockedByRecipient = useMemo(() => {
        if(!recipient || !currentUser?.blockedBy) return false;
        return !!currentUser?.blockedBy?.[recipient.uid]
    }, [currentUser, recipient]);


    useEffect(() => {
        if (!recipient) return;

        if (recipient.isGroup) {
            setClientReadyStatus(null);
        } else if ((recipient as User).isOnline) {
            setClientReadyStatus(t('online'));
        } else if ((recipient as User).lastSeen) {
            try {
                const lastSeenText = t('lastSeen', { time: formatDistanceToNow(new Date((recipient as User).lastSeen as number), { addSuffix: true }) });
                setClientReadyStatus(lastSeenText);
            } catch (error) {
                setClientReadyStatus(t('offline'));
            }
        } else {
            setClientReadyStatus(t('offline'));
        }
    }, [recipient, t, formatDistanceToNow]);
    

    const handleConfirmAction = async () => {
        if (!confirmAction || !chatId) return;

        playSound('touch');
        switch (confirmAction.type) {
            case 'block':
                // await blockUser(recipient);
                break;
            case 'unblock':
                // await unblockUser(recipient);
                break;
            case 'remove':
                onClose(); 
                break;
            case 'clear_history':
                await clearChatHistory(chatId);
                break;
        }
        setConfirmAction(null);
    };

    const handleDeleteMessage = () => {
        if (messageToDelete && messageToDelete.id && chatId) {
            playSound('touch');
            setDeletingMessageId(messageToDelete.id);
            setTimeout(() => {
                deleteMessage(chatId, messageToDelete.id!);
                setDeletingMessageId(null);
            }, 400); 
        }
        setMessageToDelete(null);
    };
    
    const handleGetSuggestedReplies = useCallback(async (message: Message): Promise<string[]> => {
        if (!message.text) return [];
        return generateSuggestedReplies(message.text, language);
    }, [language]);
    
    const handleSummarizeChat = async () => {
        if (messages.length === 0) {
            addToast("Chat is empty, nothing to summarize.", { variant: 'default' });
            return;
        }
        setIsSummarizing(true);
        setSummary(null); 
    
        const localSummary = generateLocalSummary(messages, currentUser!);
        setSummary(localSummary);
    };

    const handlePrivateReply = useCallback(({ displayName, uid }: { displayName: string, uid: string }) => {
        if (editorRef.current) {
            const firstLetter = displayName.split(' ').map(n => n[0]).join('').toLowerCase();
            editorRef.current.innerHTML = `@'${'\'\''}${firstLetter} `;
            editorRef.current.focus();
            
            // Move cursor to the end
            const range = document.createRange();
            const sel = window.getSelection();
            range.selectNodeContents(editorRef.current);
            range.collapse(false);
            sel?.removeAllRanges();
            sel?.addRange(range);
        }
    }, []);

    const handleMarkAsViewed = useCallback((messageId: string) => {
        setViewedOnceMessages(prev => new Set(prev).add(messageId));
    }, []);

    const handleEmojiSelect = (emojiData: any) => {
        const editor = editorRef.current;
        if (!editor) return;
    
        let range: Range;
    
        if (lastRange.current && editor.contains(lastRange.current.commonAncestorContainer)) {
            range = lastRange.current;
        } else {
            range = document.createRange();
            range.selectNodeContents(editor);
            range.collapse(false);
        }
    
        range.deleteContents();
    
        const img = document.createElement('img');
        img.src = emojiData.imageUrl;
        img.alt = emojiData.emoji;
        img.className = 'emoji';
        
        range.insertNode(img);
    
        range.setStartAfter(img);
        range.collapse(true);
        lastRange.current = range.cloneRange();
    
        setIsEmojiPickerOpen(false);
    };


    if (!currentUser || !recipient) {
         return null;
    }

    const lastMessage = messages.length > 0 ? messages[messages.length - 1] : null;
    const recipientStatus = clientReadyStatus;
    const canCall = !recipient.isGroup && !isBlockedByRecipient && !isBlockedByYou;
    
    
    const handleSummaryModalClose = () => {
        setIsSummarizing(false);
        setSummary(null);
    }
    
    const toggleSearch = () => {
        setIsSearching(!isSearching);
        setSearchQuery('');
    };

    return (
        <div className="flex flex-col h-full w-full flex-1">
            <div className="chat-window-background z-0"></div>
            <header className="flex-shrink-0 flex items-center justify-between p-2 md:p-4 border-b sticky top-0 z-10 glass-header">
                 <div className="flex items-center gap-3 flex-1 min-w-0">
                    <Button onClick={() => { playSound('touch'); onClose(); }} variant="ghost" size="icon" className="md:hidden">
                        <ArrowLeft />
                    </Button>
                    {!isSearching ? (
                        <button onClick={() => { if (!recipient.isGroup) { playSound('touch'); onViewProfile(recipient as User); } }} className="flex items-center gap-3 cursor-pointer disabled:cursor-default min-w-0" disabled={recipient.isGroup}>
                            <div className="relative">
                                <Avatar>
                                    <AvatarImage src={recipient.photoURL} alt={recipient.displayName} />
                                    <AvatarFallback>{recipient.displayName?.charAt(0) ?? '?'}</AvatarFallback>
                                </Avatar>
                                {(recipient as User).isOnline && !recipient.isGroup && (
                                    <span className="absolute bottom-0 right-0 block h-3 w-3 rounded-full bg-green-500 ring-2 ring-card" />
                                )}
                            </div>
                            <div className="text-left truncate">
                                <h2 className="font-bold text-lg text-foreground truncate">{recipient.displayName}</h2>
                                {recipientStatus && <p className="text-xs text-muted-foreground truncate">{recipientStatus}</p>}
                            </div>
                        </button>
                    ) : (
                        <div className="relative w-full flex items-center gap-2">
                            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
                            <Input
                                placeholder={t('searchInChat')}
                                value={searchQuery}
                                onChange={(e) => setSearchQuery(e.target.value)}
                                className="pl-10 bg-muted border-none focus-visible:ring-primary w-full"
                                autoFocus
                            />
                        </div>
                    )}
                </div>
                <div className="flex items-center gap-1">
                    <Button onClick={toggleSearch} variant="ghost" size="icon" className="rounded-full">
                        {isSearching ? <X /> : <Search />}
                    </Button>
                    {canCall && (
                        <>
                            <Button onClick={() => onStartCall(recipient as User, 'audio')} variant="outline" size="icon" className="rounded-full hover:bg-green-500/10 hover:text-green-500">
                                <Phone />
                            </Button>
                            <Button onClick={() => onStartCall(recipient as User, 'video')} variant="outline" size="icon" className="rounded-full hover:bg-blue-500/10 hover:text-blue-500">
                                <Video />
                            </Button>
                        </>
                    )}
                    {recipient.isGroup && (
                        <Button variant="ghost" size="icon" title={t('groupInfo')} onClick={() => { playSound('touch'); setGroupInfoOpen(true); }}>
                            <Info />
                        </Button>
                    )}
                    <DropdownMenu onOpenChange={() => playSound('touch')}>
                        <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="icon" title="More options">
                                <MoreVertical />
                            </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent>
                             <DropdownMenuItem onSelect={handleSummarizeChat}>
                                <FileText className="mr-2 h-4 w-4" />
                                {t('summarizeChat')}
                            </DropdownMenuItem>
                            <DropdownMenuItem onSelect={() => setConfirmAction({ type: 'clear_history' })}>
                                <MessageCircleX className="mr-2 h-4 w-4" />
                                {t('clearHistory')}
                            </DropdownMenuItem>
                            {!recipient.isGroup && (
                                <>
                                    {isBlockedByYou ? (
                                        <DropdownMenuItem onSelect={() => setConfirmAction({ type: 'unblock' })}>
                                            {t('unblockUser')}
                                        </DropdownMenuItem>
                                    ) : (
                                        <DropdownMenuItem onSelect={() => setConfirmAction({type: 'block'})} className="text-destructive">
                                            {t('blockUser')}
                                        </DropdownMenuItem>
                                    )}
                                    <DropdownMenuItem onSelect={() => setConfirmAction({type: 'remove'})} className="text-destructive">
                                        {t('removeContact')}
                                    </DropdownMenuItem>
                                </>
                            )}
                        </DropdownMenuContent>
                    </DropdownMenu>
                </div>
            </header>
            
            <div className="flex-1 flex flex-col min-h-0 relative">
                {(isBlockedByYou || isBlockedByRecipient) && <BlockedBanner recipient={recipient} isBlockedByYou={!!isBlockedByYou} t={t} />}
                
                <div ref={chatContainerRef} className="flex-1 overflow-y-auto p-4 md:p-6 chat-container">
                    {loading ? (
                        <div className="space-y-4">
                            {[...Array(3)].map((_, i) => (
                                <div key={i} className={cn("flex items-center gap-3", i % 2 === 1 && "flex-row-reverse")}>
                                    <Skeleton className="h-8 w-8 rounded-full" />
                                    <Skeleton className={cn("h-16", i % 2 === 1 ? "w-3/4" : "w-1/2")} />
                                </div>
                            ))}
                        </div>
                    ) : (
                        messages.map(msg => (
                            <MessageItem
                                key={msg.id}
                                message={msg}
                                isSender={msg.sender === currentUser.uid}
                                isDeleting={deletingMessageId === msg.id}
                                onDelete={() => { playSound('touch'); setMessageToDelete(msg); }}
                                onToggleReaction={(emoji) => { msg.id && toggleReaction(msg.id, emoji); }}
                                onPreviewImage={onPreviewImage}
                                onEditMessage={(messageId, newText) => editMessage(messageId, newText)}
                                onTranslate={() => {}}
                                onPrivateReply={handlePrivateReply}
                                currentGroup={currentGroup}
                                searchQuery={searchQuery}
                                isHighlighted={isSearching}
                                isViewed={viewedOnceMessages.has(msg.id)}
                                onMarkAsViewed={handleMarkAsViewed}
                            />
                        ))
                    )}
                    {typingUsers.length > 0 && (
                        <div className="flex items-center gap-2 p-2 text-muted-foreground">
                            <div className="typing-indicator">
                                <span></span>
                                <span></span>
                                <span></span>
                            </div>
                            <span className="text-sm italic">
                                {typingUsers.join(', ')} {typingUsers.length > 1 ? t('typing_plural') : t('typing')}
                            </span>
                        </div>
                    )}
                    <div ref={messagesEndRef} />
                </div>
                 <div className="flex-shrink-0">
                    <MessageInput 
                        sendTextMessage={sendTextMessage}
                        onSelectMedia={(file) => setMediaFile({ file, originalSize: file.size })}
                        onSendAudio={(data) => setAudioToSend(data)}
                        chatId={chatId || null}
                        disabled={!!isBlockedByYou || !!isBlockedByRecipient}
                        lastMessage={lastMessage}
                        onGetSuggestedReplies={handleGetSuggestedReplies}
                        isGroupChat={!!recipient.isGroup}
                        currentGroup={currentGroup}
                        editorRef={editorRef}
                        onToggleEmojiPicker={() => {
                            playSound('touch');
                            const willOpen = !isEmojiPickerOpen;
                            if (willOpen) {
                                // Save cursor position before blurring
                                const selection = window.getSelection();
                                if (selection && selection.rangeCount > 0 && editorRef.current?.contains(selection.anchorNode)) {
                                    lastRange.current = selection.getRangeAt(0).cloneRange();
                                }
                                // Blur the input to prevent keyboard from opening on mobile
                                editorRef.current?.blur();
                            }
                            setIsEmojiPickerOpen(willOpen);
                        }}
                        isEmojiPickerOpen={isEmojiPickerOpen}
                    />
                    <div className={cn("emoji-picker-sheet-container", isEmojiPickerOpen && "open")}>
                        <EmojiPicker
                            onEmojiClick={handleEmojiSelect}
                            autoFocusSearch={false}
                            theme={theme === 'dark' ? EmojiTheme.DARK : EmojiTheme.LIGHT}
                            emojiStyle={EmojiStyle.APPLE}
                            height="100%"
                            width="100%"
                            lazyLoadEmojis
                            searchDisabled
                            skinTonesDisabled
                            previewConfig={{ showPreview: false }}
                        />
                    </div>
                </div>
            </div>
            
            {currentGroup && (
                <GroupInfoPanel 
                    isOpen={isGroupInfoOpen}
                    onClose={() => setGroupInfoOpen(false)}
                    group={currentGroup}
                    onAddMembers={() => onAddMembers(currentGroup)}
                />
            )}
            
            {mediaFile && (
                <MediaPreviewModal
                    file={mediaFile.file}
                    originalSize={mediaFile.originalSize}
                    isOpen={!!mediaFile}
                    onClose={() => setMediaFile(null)}
                    onSend={sendMediaMessage}
                />
            )}
             {audioToSend && (
                <SendAudioModal
                    file={audioToSend.file}
                    duration={audioToSend.duration}
                    isOpen={!!audioToSend}
                    onClose={() => setAudioToSend(null)}
                    onSend={sendVoiceMessage}
                />
            )}


            <AlertDialog open={!!confirmAction} onOpenChange={(isOpen) => !isOpen && setConfirmAction(null)}>
                <AlertDialogContent className="scaleIn">
                    <AlertDialogHeader>
                        <AlertDialogTitle>{t('areYouSure')}</AlertDialogTitle>
                        <AlertDialogDescription>
                           {confirmAction?.type === 'block' && t('blockUserConfirm', { name: recipient.displayName })}
                           {confirmAction?.type === 'unblock' && t('unblockUserConfirm', { name: recipient.displayName })}
                           {confirmAction?.type === 'remove' && t('removeContactConfirm', { name: recipient.displayName })}
                           {confirmAction?.type === 'clear_history' && t('clearHistoryConfirm', { name: recipient.displayName })}
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel onClick={() => playSound('touch')}>{t('cancel')}</AlertDialogCancel>
                        <AlertDialogAction onClick={handleConfirmAction} className={confirmAction?.type === 'block' || confirmAction?.type === 'remove' ? 'bg-destructive hover:bg-destructive/90' : ''}>
                            {t('confirm')}
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
            
            <AlertDialog open={!!messageToDelete} onOpenChange={(isOpen) => !isOpen && setMessageToDelete(null)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>{t('deleteMessageTitle')}</AlertDialogTitle>

                        <AlertDialogDescription>
                            {t('deleteMessageConfirm')}
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel onClick={() => playSound('touch')}>{t('cancel')}</AlertDialogCancel>
                        <AlertDialogAction onClick={handleDeleteMessage} className="bg-destructive hover:bg-destructive/90">
                            {t('delete')}
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
            
            <AlertDialog open={isSummarizing} onOpenChange={(isOpen) => !isOpen && handleSummaryModalClose()}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>{t('chatSummary')}</AlertDialogTitle>
                        <AlertDialogDescription>
                            A quick overview of the chat.
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    {summary ? (
                        <div className="max-h-60 overflow-y-auto p-4 bg-muted rounded-lg text-sm space-y-2">
                           <p><strong>Topic:</strong> {summary.topic}</p>
                           <p><strong>Participants:</strong> {Array.isArray(summary.participants) ? summary.participants.join(', ') : ''}</p>
                           <div><strong>Summary:</strong>
                                <ul className="list-disc pl-5 mt-1">
                                    {summary.summaryPoints.map((point, index) => <li key={index}>{point}</li>)}
                                </ul>
                           </div>
                        </div>
                    ) : (
                        <div className="flex items-center justify-center p-8">
                            <Loader2 className="h-8 w-8 animate-spin" />
                        </div>
                    )}
                    <AlertDialogFooter>
                        <AlertDialogAction onClick={handleSummaryModalClose}>{t('close')}</AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
    );
}
    
