import { useState, useEffect, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import { createPortal } from 'react-dom';
import api, { useAuthStore } from '../store/auth';
import { useRealtimeStore } from '../store/realtime';
import { createAxiosUploadProgressHandler } from '../lib/uploadProgress';
import ProgressBar from '../components/ui/ProgressBar';
import { 
  Send, Search, MoreVertical, 
  MessageSquare, UserCircle, CheckCircle2,
  Sparkles, X, Users, ArrowLeft,
  Paperclip, Info, CheckCheck, Plus, UsersRound,
  FileText, Image, Download, Trophy, Eye, ZoomIn,
  Clock as ClockIcon, Check as CheckIcon,
} from 'lucide-react';

interface Conversation {
  other_user_id: string | number;
  other_user_name: string;
  last_message: string;
  last_message_at: string;
  unread_count: number;
  last_sender_id?: number;
  last_is_read?: number;
  last_is_delivered?: number;
  last_id?: number;
}

interface ChatMessage {
  id: number;
  uid: string;
  sender_id: number;
  sender_name?: string;
  recipient_id: number;
  recipient_name?: string;
  subject: string;
  body: string;
  is_read: number;
  is_delivered?: number;
  is_announcement: number;
  priority: string;
  created_at: string;
  direction?: 'sent' | 'received';
  attachment_url?: string;
  attachment_name?: string;
  attachment_type?: string;
  /**
   * Transient flag set on optimistic sends. True while the message is
   * still in the local outbox (no real server id yet). Cleared when the
   * server-side reload replaces it with the persisted message.
   */
  pending?: boolean;
}

const getFileType = (url: string, type?: string) => {
  if (type) return type;
  const ext = url.split('.').pop()?.toLowerCase();
  if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext || '')) {
    return 'image/' + (ext === 'jpg' ? 'jpeg' : ext);
  }
  if (ext === 'pdf') return 'application/pdf';
  if (['txt', 'csv', 'log', 'json', 'xml', 'md'].includes(ext || '')) return 'text/plain';
  return 'application/octet-stream';
};

/**
 * Renders the appropriate status icon for a sent message:
 *   - Clock          → still in the local outbox (queued, offline, or
 *                      optimistic send still pending server ack)
 *   - Single gray ✓  → server has accepted the message but the
 *                      recipient has not fetched it yet (`is_delivered = 0`)
 *   - Double gray ✓✓ → recipient has fetched the message but not opened
 *                      it yet (`is_delivered = 1`, `is_read = 0`)
 *   - Double blue ✓✓ → recipient has read the message (`is_read = 1`)
 *
 * Groups/clubs/announcements don't have per-recipient delivery state, so
 * we treat them as fully read (blue ticks) when they appear here.
 */
function renderMessageStatus(msg: ChatMessage) {
  if (msg.pending || (typeof msg.id === 'number' && msg.id > 1e12)) {
    return <ClockIcon size={14} className="opacity-80 leading-none" />;
  }
  if (msg.is_read === 1) {
    return <CheckCheck size={14} className="text-sky-300 leading-none" />;
  }
  if (msg.is_delivered === 1) {
    return <CheckCheck size={14} className="opacity-80 leading-none" />;
  }
  return <CheckIcon size={14} className="opacity-80 leading-none" />;
}

/**
 * Per-conversation status icon shown in the chat list next to the last
 * message preview. Only meaningful for direct messages whose last
 * message was sent by the current user; otherwise we just show the
 * last-message time (and the unread badge already covers the inbound
 * case).
 *
 * Returns the right widget for the row:
 *   - the user sent the last message → clock / 1 tick / 2 ticks / blue
 *   - the other party sent it        → null (let the time + unread badge
 *                                                  carry the row)
 */
function renderConversationStatus(conv: Conversation, currentUserId?: number | string) {
  if (conv.last_sender_id === undefined || conv.last_sender_id === null) return null;
  if (String(conv.last_sender_id) !== String(currentUserId ?? '')) return null;
  if (conv.last_is_read === 1) {
    return <CheckCheck size={14} className="text-sky-500 shrink-0" />;
  }
  if (conv.last_is_delivered === 1) {
    return <CheckCheck size={14} className="text-text-muted shrink-0" />;
  }
  return <CheckIcon size={14} className="text-text-muted shrink-0" />;
}

export default function Messages() {
  const { user } = useAuthStore();
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [activeChatId, setActiveChatId] = useState<string | number | null>(null);
  const [activeChatName, setActiveChatName] = useState<string>('');
  
  const [chatMessages, setChatMessages] = useState<ChatMessage[]>([]);
  const [newMessage, setNewMessage] = useState('');
  
  const [showContacts, setShowContacts] = useState(false);
  const [isCreatingGroup, setIsCreatingGroup] = useState(false);
  const [groupName, setGroupName] = useState('');
  const [selectedContactIds, setSelectedContactIds] = useState<number[]>([]);

  const [contacts, setContacts] = useState<any[]>([]);
  const [searchQuery, setSearchQuery] = useState('');
  
  const [loading, setLoading] = useState(true);
  const [chatLoading, setChatLoading] = useState(false);

  const [attachment, setAttachment] = useState<{ url: string; name: string; type: string } | null>(null);
  const [uploading, setUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState<number>(0);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const activeChatIdRef = useRef<string | number | null>(null);

  const [searchParams] = useSearchParams();
  const paramChat = searchParams.get('chat');

  useEffect(() => {
    activeChatIdRef.current = activeChatId;
  }, [activeChatId]);

  useEffect(() => {
    if (paramChat) {
      if (paramChat === 'announcements') {
        setActiveChatId('announcements');
        setActiveChatName('Announcements');
      } else {
        const idVal = isNaN(Number(paramChat)) ? paramChat : Number(paramChat);
        setActiveChatId(idVal);
        const conv = conversations.find((c) => String(c.other_user_id) === String(paramChat));
        if (conv) {
          setActiveChatName(conv.other_user_name);
        } else if (!isNaN(Number(paramChat))) {
          api.get(`/users/${paramChat}`).then((res) => {
            if (res.data) {
              const name = `${res.data.first_name || ''} ${res.data.last_name || ''}`.trim();
              if (name) setActiveChatName(name);
            }
          }).catch(() => {});
        }
      }
    }
  }, [paramChat, conversations]);

  const [previewAttachment, setPreviewAttachment] = useState<{ url: string; name: string; type: string } | null>(null);
  const [textContent, setTextContent] = useState<string | null>(null);
  const [loadingText, setLoadingText] = useState(false);
  const [zoomScale, setZoomScale] = useState(1);

  useEffect(() => {
    if (!previewAttachment) {
      setTextContent(null);
      setZoomScale(1);
      return;
    }

    const type = getFileType(previewAttachment.url, previewAttachment.type);
    if (type.startsWith('text/') || ['text/plain', 'text/csv', 'text/html', 'application/json'].includes(type)) {
      setLoadingText(true);
      fetch(previewAttachment.url)
        .then(res => {
          if (!res.ok) throw new Error('Network response was not ok');
          return res.text();
        })
        .then(text => {
          setTextContent(text);
          setLoadingText(false);
        })
        .catch(err => {
          console.error(err);
          setTextContent('Failed to load text content.');
          setLoadingText(false);
        });
    }
  }, [previewAttachment]);

  const handleDownload = (url: string, name: string) => {
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', name);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const formData = new FormData();
    formData.append('file', file);

    setUploading(true);
    setUploadProgress(0);
    try {
      const res = await api.post('/messages/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        onUploadProgress: createAxiosUploadProgressHandler((percent) => {
          if (typeof percent === 'number') {
            setUploadProgress(percent);
          }
        })
      });
      setAttachment({
        url: res.data.fileUrl,
        name: res.data.fileName,
        type: res.data.fileType
      });
    } catch (err) {
      alert('Failed to upload file');
      console.error(err);
    } finally {
      setUploading(false);
      setUploadProgress(0);
      if (fileInputRef.current) fileInputRef.current.value = '';
    }
  };

  useEffect(() => {
    loadConversations();
    loadContacts();

    // Auto-refresh conversations every 30 seconds (fallback)
    const interval = setInterval(loadConversations, 30000);
    return () => clearInterval(interval);
  }, []);

  // WebSocket subscription for real-time message delivery.
  // PR 3 §13 follow-up — switched to the shared useRealtimeStore so the
  // student dashboard, parent AcademicProgress, and this page all share
  // a single socket connection. Falls back to the 30s polling above if
  // the connection drops.
  useEffect(() => {
    const handleIncoming = (payload: any) => {
      const type = payload?.type;
      const incoming = payload?.data?.message ?? payload?.data;
      if (type === 'message:new') {
        if (!incoming) return;
        const otherId = incoming.sender_id === user?.id ? incoming.recipient_id : incoming.sender_id;
        if (otherId && String(activeChatId) === String(otherId)) {
          setChatMessages((prev) => {
            if (prev.some((m) => m.id === incoming.id)) return prev;
            return [...prev, { ...incoming, direction: incoming.direction || 'received' }];
          });
        }
        loadConversations();
        setTimeout(scrollToBottom, 50);
      } else if (type === 'message:sent') {
        loadConversations();
      } else if (type === 'announcement:new') {
        if (activeChatId === 'announcements') {
          setChatMessages((prev) => {
            if (prev.some((m) => m.id === incoming.id)) return prev;
            return [...prev, { ...incoming, direction: incoming.direction || 'received' }];
          });
          setTimeout(scrollToBottom, 50);
        }
        loadConversations();
      }
    };

    const unsubA = useRealtimeStore.getState().subscribe('message:new', handleIncoming);
    const unsubB = useRealtimeStore.getState().subscribe('message:sent', handleIncoming);
    const unsubC = useRealtimeStore.getState().subscribe('announcement:new', handleIncoming);
    return () => { unsubA(); unsubB(); unsubC(); };
    // loadConversations and scrollToBottom are stable (defined inside the component but
// they read from state via setter functions, so a one-shot subscribe is fine).
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeChatId]);

  useEffect(() => {
    if (activeChatId) {
      loadActiveChat(activeChatId);
    }
  }, [activeChatId]);

  useEffect(() => {
    scrollToBottom();
  }, [chatMessages]);

  useEffect(() => {
    if (!window.visualViewport) return;
    const handleViewportChange = () => {
      messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
    };
    window.visualViewport.addEventListener('resize', handleViewportChange);
    window.visualViewport.addEventListener('scroll', handleViewportChange);
    return () => {
      window.visualViewport?.removeEventListener('resize', handleViewportChange);
      window.visualViewport?.removeEventListener('scroll', handleViewportChange);
    };
  }, []);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  const loadConversations = async () => {
    try {
      const res = await api.get('/messages/conversations');
      setConversations(res.data);
    } catch (err) {
      console.error('Failed to load conversations');
    } finally {
      setLoading(false);
    }
  };

  const loadActiveChat = async (id: string | number, silent = false) => {
    if (!silent) setChatLoading(true);
    try {
      if (id === 'announcements') {
        const res = await api.get('/messages/announcements');
        setChatMessages(res.data.reverse());
      } else {
        const res = await api.get(`/messages/conversation/${id}`);
        setChatMessages(res.data.reverse());
        if (!silent) loadConversations();
      }
    } catch (err) {
      console.error('Failed to load chat');
    } finally {
      if (!silent) setChatLoading(false);
    }
  };

  const loadContacts = async () => {
    try {
        const res = await api.get('/messages/contacts');
        setContacts(res.data);
    } catch (err) {
        console.error('Failed to load contacts');
    }
  };

  const handleCreateGroup = async () => {
      if (!groupName.trim() || selectedContactIds.length === 0) return;
      try {
          const res = await api.post('/messages/groups', {
              name: groupName.trim(),
              member_ids: selectedContactIds
          });
          setShowContacts(false);
          setIsCreatingGroup(false);
          setGroupName('');
          setSelectedContactIds([]);
          selectChat(res.data.id, res.data.name);
          loadConversations();
      } catch (err) {
          alert('Failed to create group');
      }
  };

  const handleSend = async (e: React.FormEvent) => {
    e.preventDefault();
    if ((!newMessage.trim() && !attachment) || !activeChatId) return;

    const bodyText = newMessage.trim();
    setNewMessage(''); // optimistic clear
    const currentAttachment = attachment;
    setAttachment(null); // clear

    // Optimistic UI update
    const tempId = Date.now();
    const optimisticMsg: ChatMessage = {
        id: tempId,
        uid: `temp-${tempId}`,
        sender_id: user?.id || 0,
        recipient_id: typeof activeChatId === 'number' ? activeChatId : 0,
        subject: bodyText ? (bodyText.length > 30 ? bodyText.substring(0, 30) + '...' : 'Chat Message') : 'Attachment',
        body: bodyText,
        is_read: 0,
        is_announcement: activeChatId === 'announcements' ? 1 : 0,
        priority: 'normal',
        created_at: new Date().toISOString(),
        direction: 'sent',
        sender_name: user ? `${user.first_name} ${user.last_name}` : 'Me',
        attachment_url: currentAttachment?.url,
        attachment_name: currentAttachment?.name,
        attachment_type: currentAttachment?.type,
        pending: true,
    };
    
    setChatMessages(prev => [...prev, optimisticMsg]);
    setTimeout(scrollToBottom, 50);

    try {
        if (activeChatId === 'announcements') {
            await api.post('/messages/announcements', { 
                subject: 'System Broadcast', 
                body: bodyText, 
                priority: 'normal',
                attachment_url: currentAttachment?.url,
                attachment_name: currentAttachment?.name,
                attachment_type: currentAttachment?.type
            });
        } else {
            await api.post('/messages', { 
                recipient_id: activeChatId, 
                subject: optimisticMsg.subject, 
                body: bodyText,
                is_announcement: false,
                attachment_url: currentAttachment?.url,
                attachment_name: currentAttachment?.name,
                attachment_type: currentAttachment?.type
            });
        }
        // Silent reload so chat doesn't flash
        await loadActiveChat(activeChatId, true);
        loadConversations(); // background refresh of list
    } catch (err) {
        alert('Failed to send message');
        setChatMessages(prev => prev.filter(m => m.id !== tempId));
        setNewMessage(bodyText); // restore on fail
        setAttachment(currentAttachment); // restore attachment
    }
  };

  const selectChat = (id: string | number, name: string) => {
      setActiveChatId(id);
      setActiveChatName(name);
  };

  const filteredConversations = conversations.filter(c =>
    (c.other_user_name || '').toLowerCase().includes(searchQuery.toLowerCase())
  );

  const filteredContacts = contacts.filter(c => 
    `${c.first_name} ${c.last_name}`.toLowerCase().includes(searchQuery.toLowerCase())
  );

  // Group contacts by role for the new chat modal
  const groupedContacts = filteredContacts.reduce((acc, c) => {
      acc[c.role] = acc[c.role] || [];
      acc[c.role].push(c);
      return acc;
  }, {} as Record<string, any[]>);

  // Mirror the server-side allowlist on POST /api/messages/announcements
  // (server/src/controllers/messages.controller.js) so any admin / teacher
  // role permitted by the API actually sees the broadcast composer in
  // the UI. Previously systems_admin was excluded from this check,
  // silently hiding the broadcast composer for that role.
  const canSendAnnouncements =
    user?.role === 'school_admin' ||
    user?.role === 'systems_admin' ||
    user?.role === 'principal' ||
    user?.role === 'teacher';

  return (
    <div className="h-[calc(100dvh-70px)] md:h-[calc(100vh-100px)] max-h-[100dvh] flex bg-card border border-border rounded-2xl md:rounded-3xl shadow-sm overflow-hidden animate-in fade-in duration-500">
        
      {/* Left Pane: Conversations List */}
      <div className={`w-full md:w-[350px] lg:w-[400px] border-r border-border flex flex-col bg-background/50 ${activeChatId ? 'hidden md:flex' : 'flex'}`}>
        {/* Header */}
        <div className="h-16 px-4 bg-card border-b border-border flex items-center justify-between shrink-0">
            <div className="flex items-center gap-3">
                <div className="w-10 h-10 rounded-full bg-gradient-to-br from-primary to-primary-dark text-white flex items-center justify-center font-bold shadow-md">
                    {user?.first_name?.[0]}{user?.last_name?.[0]}
                </div>
                <h2 className="font-bold text-text">Chats</h2>
            </div>
            <button 
                onClick={() => setShowContacts(true)}
                className="w-10 h-10 rounded-full hover:bg-muted flex items-center justify-center text-text-muted transition-colors"
                title="New Chat"
            >
                <MessageSquare size={20} />
            </button>
        </div>

        {/* Search */}
        <div className="p-3 bg-background/50 border-b border-border shrink-0">
            <div className="relative">
                <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-text-muted" />
                <input 
                    type="text" 
                    placeholder="Search chats..." 
                    className="w-full bg-card border border-border rounded-xl pl-10 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all text-text"
                    value={searchQuery}
                    onChange={e => setSearchQuery(e.target.value)}
                />
            </div>
        </div>

        {/* List */}
        <div className="flex-1 overflow-y-auto custom-scrollbar">
            {/* System Broadcasts Fixed Item */}
            <div 
                onClick={() => selectChat('announcements', 'System Broadcasts')}
                className={`px-4 py-3 flex items-center gap-3 cursor-pointer transition-colors border-b border-border/50 ${activeChatId === 'announcements' ? 'bg-primary/5' : 'hover:bg-muted/50'}`}
            >
                <div className="w-12 h-12 rounded-full bg-purple-50 dark:bg-purple-900/30 flex items-center justify-center text-purple-600 dark:text-purple-400 shrink-0 border border-purple-100 dark:border-purple-800">
                    <Sparkles size={22} />
                </div>
                <div className="flex-1 min-w-0">
                    <h4 className="text-sm font-bold text-text truncate">System Broadcasts</h4>
                    <p className="text-[0.7rem] text-purple-500 truncate font-medium mt-0.5">Official Announcements</p>
                </div>
            </div>

            {loading ? (
                <div className="flex justify-center p-8"><div className="w-6 h-6 border-2 border-primary border-t-transparent rounded-full animate-spin"></div></div>
            ) : filteredConversations.map(conv => (
                <div 
                    key={conv.other_user_id}
                    onClick={() => selectChat(conv.other_user_id, conv.other_user_name)}
                    className={`px-4 py-3 flex items-center gap-3 cursor-pointer transition-colors border-b border-border/50 ${activeChatId === conv.other_user_id ? 'bg-primary/5' : 'hover:bg-muted/50'}`}
                >
                    <div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold shrink-0 shadow-sm ${
                        String(conv.other_user_id).startsWith('c_') 
                            ? 'bg-orange-500/10 text-orange-500 border border-orange-200 dark:border-orange-900/30' 
                            : String(conv.other_user_id).startsWith('g_')
                                ? 'bg-blue-600/10 text-blue-600 border border-blue-200 dark:border-blue-900/30'
                                : 'bg-muted text-text-muted'
                    }`}>
                        {String(conv.other_user_id).startsWith('c_') ? (
                            <Trophy size={20} />
                        ) : String(conv.other_user_id).startsWith('g_') ? (
                            <Users size={20} />
                        ) : (
                            conv.other_user_name?.[0] || <UserCircle size={24} />
                        )}
                    </div>
                    <div className="flex-1 min-w-0">
                        <div className="flex justify-between items-baseline mb-0.5">
                            <h4 className="text-sm font-bold text-text truncate">{conv.other_user_name}</h4>
                            <span className={`text-[0.65rem] ${conv.unread_count > 0 ? 'text-emerald-500 font-bold' : 'text-text-muted'}`}>
                                {new Date(conv.last_message_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
                            </span>
                        </div>
                        <div className="flex items-center gap-1">
                            {renderConversationStatus(conv, user?.id)}
                            <p className={`text-[0.8rem] truncate ${conv.unread_count > 0 ? 'text-text font-semibold' : 'text-text-muted'}`}>
                                {conv.last_message}
                            </p>
                        </div>
                    </div>
                    {conv.unread_count > 0 && (
                        <div className="w-5 h-5 rounded-full bg-emerald-500 text-white flex items-center justify-center text-[0.65rem] font-bold shrink-0 shadow-sm">
                            {conv.unread_count}
                        </div>
                    )}
                </div>
            ))}
            {!loading && filteredConversations.length === 0 && !searchQuery && (
                <div className="p-8 text-center text-text-muted text-sm">
                    No active chats. Click the message icon to start a new conversation.
                </div>
            )}
        </div>
      </div>


      {/* Right Pane: Active Chat Area */}
      <div className={`flex-1 flex flex-col min-w-0 bg-[url('/chat-bg-light.png')] dark:bg-[url('/chat-bg-dark.png')] bg-repeat opacity-95 ${!activeChatId ? 'hidden md:flex bg-muted/10' : 'flex'}`}>
        {activeChatId ? (
            <>
                {/* Chat Header */}
                <div className="h-16 px-4 bg-card border-b border-border flex items-center justify-between shrink-0 shadow-sm z-10">
                    <div className="flex items-center gap-3">
                        <button className="md:hidden p-2 -ml-2 text-text-muted hover:text-text rounded-full hover:bg-muted transition-colors" onClick={() => setActiveChatId(null)}>
                            <ArrowLeft size={20} />
                        </button>
                        <div className={`w-10 h-10 rounded-full flex items-center justify-center font-bold shrink-0 ${
                            activeChatId === 'announcements' 
                                ? 'bg-purple-500 text-white' 
                                : String(activeChatId).startsWith('c_')
                                    ? 'bg-orange-500/10 text-orange-500 border border-orange-200 dark:border-orange-900/30'
                                    : String(activeChatId).startsWith('g_')
                                        ? 'bg-blue-600/10 text-blue-600 border border-blue-200 dark:border-blue-900/30'
                                        : 'bg-muted text-text-muted'
                        }`}>
                            {activeChatId === 'announcements' ? (
                                <Sparkles size={18} />
                            ) : String(activeChatId).startsWith('c_') ? (
                                <Trophy size={18} />
                            ) : String(activeChatId).startsWith('g_') ? (
                                <Users size={18} />
                            ) : (
                                activeChatName?.[0]
                            )}
                        </div>
                        <div>
                            <h3 className="font-bold text-text leading-tight">{activeChatName}</h3>
                            <p className="text-[0.65rem] text-text-muted">
                                {activeChatId === 'announcements' 
                                    ? 'System-wide Broadcasts' 
                                    : String(activeChatId).startsWith('c_')
                                        ? 'Extracurricular Chatroom'
                                        : String(activeChatId).startsWith('g_')
                                            ? 'Group Conversation'
                                            : 'Tap here for contact info'}
                            </p>
                        </div>
                    </div>
                    <div className="flex items-center gap-1">
                        {activeChatId !== 'announcements' && (
                            <button className="w-10 h-10 rounded-full hover:bg-muted flex items-center justify-center text-text-muted transition-colors">
                                <Search size={18} />
                            </button>
                        )}
                        <button className="w-10 h-10 rounded-full hover:bg-muted flex items-center justify-center text-text-muted transition-colors">
                            <MoreVertical size={18} />
                        </button>
                    </div>
                </div>

                {/* Messages Area */}
                <div className="flex-1 overflow-y-auto p-4 md:p-6 space-y-3 custom-scrollbar flex flex-col" style={{ backgroundColor: 'rgba(var(--background), 0.5)', backdropFilter: 'blur(40px)' }}>
                    {chatLoading ? (
                        <div className="flex-1 flex items-center justify-center"><div className="w-8 h-8 border-3 border-primary border-t-transparent rounded-full animate-spin"></div></div>
                    ) : (
                        <>
                            <div className="flex justify-center mb-6">
                                <span className="bg-card border border-border px-3 py-1 rounded-lg text-[0.65rem] font-bold text-text-muted shadow-sm uppercase tracking-widest">
                                    End-to-End Encrypted
                                </span>
                            </div>
                            
                            {chatMessages.map((msg, index) => {
                                const isSent = msg.direction === 'sent' || (activeChatId === 'announcements' && msg.sender_id === user?.id);
                                const showSenderName = activeChatId === 'announcements' && !isSent && (index === 0 || chatMessages[index-1].sender_id !== msg.sender_id);
                                
                                return (
                                    <div key={msg.id} className={`flex ${isSent ? 'justify-end' : 'justify-start'} w-full`}>
                                        <div className={`max-w-[85%] md:max-w-[65%] flex flex-col ${isSent ? 'items-end' : 'items-start'}`}>
                                            <div className={`relative px-3.5 py-2 text-[0.9rem] shadow-sm flex flex-col ${
                                                isSent 
                                                    ? 'bg-emerald-500 text-white rounded-2xl rounded-tr-sm' 
                                                    : 'bg-card border border-border text-text rounded-2xl rounded-tl-sm'
                                            }`}>
                                                {showSenderName && (
                                                    <span className="text-[0.65rem] font-bold text-purple-500 mb-0.5">{msg.sender_name}</span>
                                                )}
                                                {msg.attachment_url && (() => {
                                                    const derivedType = getFileType(msg.attachment_url, msg.attachment_type);
                                                    const isImage = derivedType.startsWith('image/');
                                                    return (
                                                        <div className="mb-2 max-w-full rounded-lg overflow-hidden border border-border/20 bg-black/5 dark:bg-white/5">
                                                            {isImage ? (
                                                                <div 
                                                                    onClick={(e) => {
                                                                        e.preventDefault();
                                                                        setPreviewAttachment({
                                                                            url: msg.attachment_url!,
                                                                            name: msg.attachment_name || 'Image',
                                                                            type: derivedType
                                                                        });
                                                                    }}
                                                                    className="block group relative cursor-zoom-in"
                                                                >
                                                                    <img 
                                                                        src={msg.attachment_url} 
                                                                        alt={msg.attachment_name || 'Image'} 
                                                                        className="max-h-60 w-full object-cover rounded-lg group-hover:opacity-95 transition-opacity" 
                                                                    />
                                                                    <div className="absolute inset-0 bg-black/0 group-hover:bg-black/20 flex items-center justify-center transition-all">
                                                                        <ZoomIn size={24} className="text-white opacity-0 group-hover:opacity-100 transition-all transform scale-95 group-hover:scale-100" />
                                                                    </div>
                                                                </div>
                                                            ) : (
                                                                <div 
                                                                    onClick={(e) => {
                                                                        e.preventDefault();
                                                                        setPreviewAttachment({
                                                                            url: msg.attachment_url!,
                                                                            name: msg.attachment_name || 'Attachment',
                                                                            type: derivedType
                                                                        });
                                                                    }}
                                                                    className={`flex items-center gap-3 p-3 text-xs font-medium hover:bg-black/10 dark:hover:bg-white/10 cursor-pointer transition-colors ${
                                                                        isSent ? 'text-white' : 'text-text'
                                                                    }`}
                                                                >
                                                                    <div className={`p-2 rounded-lg flex items-center justify-center shrink-0 ${
                                                                        isSent ? 'bg-emerald-600 text-white' : 'bg-primary/10 text-primary'
                                                                    }`}>
                                                                        <FileText size={18} />
                                                                    </div>
                                                                    <div className="min-w-0 flex-1">
                                                                        <p className="font-bold truncate leading-tight">{msg.attachment_name || 'Attachment'}</p>
                                                                        <p className="text-[0.65rem] opacity-75 mt-0.5 uppercase tracking-wide">View / Download</p>
                                                                    </div>
                                                                    <Eye size={14} className="shrink-0 opacity-80" />
                                                                </div>
                                                            )}
                                                        </div>
                                                    );
                                                })()}
                                                {msg.body && (
                                                    <span className="whitespace-pre-wrap leading-snug break-words">
                                                        {msg.body}
                                                    </span>
                                                )}
                                                <div className={`flex items-center justify-end gap-1 mt-1 -mb-1 ${isSent ? 'text-emerald-100' : 'text-text-muted'}`}>
                                                    <span className="text-[0.6rem] font-medium leading-none">
                                                        {new Date(msg.created_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
                                                    </span>
                                                    {isSent && renderMessageStatus(msg)}
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                );
                            })}
                            <div ref={messagesEndRef} />
                        </>
                    )}
                </div>

                {/* Input Area */}
                {activeChatId === 'announcements' && !canSendAnnouncements ? (
                    <div className="p-4 bg-card border-t border-border text-center text-sm text-text-muted font-medium">
                        Only administrators can broadcast messages here.
                    </div>
                ) : (
                    <div className="flex flex-col w-full bg-card border-t border-border shrink-0 sticky bottom-0 z-20 pb-[env(safe-area-inset-bottom,0px)]">
                        {/* Attachment Uploading status */}
                        {uploading && (
                            <div className="mx-4 mt-3 p-2.5 bg-muted/30 border border-border rounded-xl flex flex-col gap-2 text-xs text-text-muted animate-pulse">
                                <div className="flex items-center gap-2.5">
                                    <div className="w-4 h-4 border-2 border-primary border-t-transparent rounded-full animate-spin"></div>
                                    <span>Uploading attachment...</span>
                                </div>
                                <ProgressBar
                                    value={uploadProgress}
                                    size="xs"
                                    aria-label="Attachment upload progress"
                                />
                            </div>
                        )}
                        {/* Attachment Selected preview */}
                        {attachment && (
                            <div className="mx-4 mt-3 p-2 bg-muted/40 border border-border rounded-xl flex items-center justify-between animate-in slide-in-from-bottom-2 duration-200">
                                <div className="flex items-center gap-2.5">
                                    {attachment.type.startsWith('image/') ? (
                                        <div className="w-10 h-10 rounded-lg bg-background border overflow-hidden flex items-center justify-center shadow-sm">
                                            <img src={attachment.url} alt="preview" className="w-full h-full object-cover" />
                                        </div>
                                    ) : (
                                        <div className="w-10 h-10 rounded-lg bg-background border flex items-center justify-center text-primary shadow-sm">
                                            <FileText size={20} />
                                        </div>
                                    )}
                                    <div className="min-w-0">
                                        <p className="text-xs font-bold text-text truncate max-w-[200px]">{attachment.name}</p>
                                        <p className="text-[0.65rem] text-emerald-500 font-semibold mt-0.5">Ready to send</p>
                                    </div>
                                </div>
                                <button 
                                    type="button" 
                                    onClick={() => setAttachment(null)}
                                    className="w-7 h-7 rounded-full hover:bg-background border border-transparent hover:border-border flex items-center justify-center text-text-muted hover:text-text transition-all"
                                >
                                    <X size={14} />
                                </button>
                            </div>
                        )}

                        <div className="p-3 flex items-end gap-2">
                            <input 
                                type="file" 
                                ref={fileInputRef} 
                                className="hidden" 
                                onChange={handleFileChange} 
                            />
                            <button 
                                type="button"
                                onClick={() => fileInputRef.current?.click()}
                                disabled={uploading}
                                className="p-3 text-text-muted hover:text-text disabled:opacity-50 rounded-full hover:bg-muted transition-colors shrink-0 cursor-pointer" 
                                title="Attach File/Image"
                            >
                                <Paperclip size={20} />
                            </button>
                            <form onSubmit={handleSend} className="flex-1 flex items-end bg-background border border-border rounded-2xl overflow-hidden focus-within:ring-2 focus-within:ring-primary/20 focus-within:border-primary transition-all">
                                <textarea 
                                    value={newMessage}
                                    onChange={e => setNewMessage(e.target.value)}
                                    onFocus={() => {
                                        setTimeout(scrollToBottom, 100);
                                        setTimeout(scrollToBottom, 300);
                                    }}
                                    onKeyDown={e => {
                                        if (e.key === 'Enter' && !e.shiftKey) {
                                            e.preventDefault();
                                            handleSend(e);
                                        }
                                    }}
                                    placeholder="Type a message..."
                                    className="flex-1 max-h-32 min-h-[44px] py-3 px-4 bg-transparent border-none focus:ring-0 text-sm text-text resize-none custom-scrollbar"
                                    rows={1}
                                />
                            </form>
                            <button 
                                onClick={handleSend}
                                disabled={!newMessage.trim() && !attachment}
                                className="p-3 rounded-full bg-primary text-white hover:bg-primary/90 transition-all shrink-0 disabled:opacity-50 disabled:grayscale flex items-center justify-center h-[44px] w-[44px] shadow-md cursor-pointer"
                            >
                                <Send size={18} className="ml-1" />
                            </button>
                        </div>
                    </div>
                )}
            </>
        ) : (
            <div className="flex-1 flex flex-col items-center justify-center p-8 text-center text-text-muted">
                <div className="w-24 h-24 rounded-full bg-muted flex items-center justify-center mb-6 border-4 border-card shadow-sm">
                    <MessageSquare size={40} className="opacity-50" />
                </div>
                <h2 className="text-xl font-bold text-text mb-2">NextGen Chat Protocol</h2>
                <p className="max-w-md text-sm leading-relaxed">
                    Select a conversation from the sidebar to view history, or click the new chat icon to start a secure communication thread.
                </p>
            </div>
        )}
      </div>

      {/* New Chat Modal / Sidebar */}
      {showContacts && createPortal(
        <div className="fixed inset-0 z-[200] flex">
            <div className="absolute inset-0 bg-black/40 backdrop-blur-sm" onClick={() => { setShowContacts(false); setIsCreatingGroup(false); setSelectedContactIds([]); }} />
            <div className="relative w-full md:w-[350px] bg-card h-full shadow-2xl flex flex-col animate-in slide-in-from-left duration-300 border-r border-border" onClick={(e) => e.stopPropagation()}>
                <div className="h-16 bg-primary px-4 flex items-center justify-between shrink-0 text-white shadow-md">
                    <div className="flex items-center gap-4">
                        <button onClick={() => { setShowContacts(false); setIsCreatingGroup(false); setSelectedContactIds([]); }} className="p-2 hover:bg-white/10 rounded-full transition-colors">
                            <ArrowLeft size={20} />
                        </button>
                        <h2 className="font-bold">{isCreatingGroup ? 'New Group' : 'New Chat'}</h2>
                    </div>
                    {!isCreatingGroup && (
                        <button 
                            onClick={() => setIsCreatingGroup(true)}
                            className="p-2 hover:bg-white/10 rounded-full transition-colors"
                            title="Create Group"
                        >
                            <UsersRound size={20} />
                        </button>
                    )}
                </div>
                
                {isCreatingGroup && (
                    <div className="p-4 bg-background border-b border-border shrink-0 space-y-3">
                        <input 
                            type="text" 
                            placeholder="Group Subject" 
                            className="w-full bg-card border border-border rounded-xl px-4 py-2 text-sm focus:outline-none focus:border-primary text-text font-bold"
                            value={groupName}
                            onChange={e => setGroupName(e.target.value)}
                        />
                        <button 
                            onClick={handleCreateGroup}
                            disabled={!groupName.trim() || selectedContactIds.length === 0}
                            className="w-full py-2 bg-emerald-500 text-white font-bold rounded-xl disabled:opacity-50 transition-colors"
                        >
                            Create ({selectedContactIds.length})
                        </button>
                    </div>
                )}

                <div className="p-3 bg-background border-b border-border shrink-0">
                    <div className="relative">
                        <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-text-muted" />
                        <input 
                            type="text" 
                            placeholder="Search contacts..." 
                            className="w-full bg-card border border-border rounded-xl pl-10 pr-4 py-2 text-sm focus:outline-none focus:border-primary text-text"
                            value={searchQuery}
                            onChange={e => setSearchQuery(e.target.value)}
                        />
                    </div>
                </div>

                <div className="flex-1 overflow-y-auto custom-scrollbar">
                    {Object.entries(groupedContacts).length === 0 ? (
                        <div className="p-8 text-center text-text-muted text-sm">No contacts found.</div>
                    ) : (
                        Object.entries(groupedContacts).map(([role, roleContacts]) => (
                            <div key={role}>
                                <div className="px-4 py-2 bg-muted/30 text-[0.65rem] font-black uppercase tracking-widest text-text-muted sticky top-0 backdrop-blur-md">
                                    {role.replace('_', ' ')}
                                </div>
                                {roleContacts.map(c => {
                                    const isSelected = selectedContactIds.includes(c.id);
                                    return (
                                        <div 
                                            key={c.id}
                                            onClick={() => {
                                                if (isCreatingGroup) {
                                                    setSelectedContactIds(prev => 
                                                        prev.includes(c.id) ? prev.filter(id => id !== c.id) : [...prev, c.id]
                                                    );
                                                } else {
                                                    setShowContacts(false);
                                                    setSearchQuery('');
                                                    selectChat(c.id, `${c.first_name} ${c.last_name}`);
                                                }
                                            }}
                                            className={`px-4 py-3 flex items-center justify-between cursor-pointer transition-colors border-b border-border/30 ${isSelected ? 'bg-primary/10' : 'hover:bg-muted/50'}`}
                                        >
                                            <div className="flex items-center gap-3">
                                                <div className="w-10 h-10 rounded-full bg-primary/10 text-primary flex items-center justify-center font-bold">
                                                    {c.first_name[0]}{c.last_name[0]}
                                                </div>
                                                <div>
                                                    <p className="text-sm font-bold text-text">{c.first_name} {c.last_name}</p>
                                                    <p className="text-[0.65rem] text-text-muted truncate">{c.email}</p>
                                                </div>
                                            </div>
                                            {isCreatingGroup && (
                                                <div className={`w-5 h-5 rounded-full border flex items-center justify-center ${isSelected ? 'bg-primary border-primary text-white' : 'border-border'}`}>
                                                    {isSelected && <CheckCheck size={12} />}
                                                </div>
                                            )}
                                        </div>
                                    );
                                })}
                            </div>
                        ))
                    )}
                </div>
            </div>
        </div>
      ,
        document.body
      )}

      {/* Attachment Preview Modal */}
      {previewAttachment && createPortal(
        <div className="fixed inset-0 z-[250] flex items-center justify-center p-4 md:p-6 animate-in fade-in duration-200">
            {/* Backdrop */}
            <div className="absolute inset-0 bg-black/80 backdrop-blur-md" onClick={() => { setPreviewAttachment(null); setTextContent(null); setZoomScale(1); }} />

            {/* Modal Body */}
            <div className="relative w-full max-w-4xl bg-card border border-border rounded-3xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh] animate-in zoom-in-95 duration-200" onClick={(e) => e.stopPropagation()}>
                {/* Header */}
                <div className="px-6 py-4 bg-muted/40 border-b border-border flex items-center justify-between shrink-0">
                    <div className="flex items-center gap-3 min-w-0">
                        <div className="p-2 rounded-xl bg-primary/10 text-primary shrink-0">
                            {getFileType(previewAttachment.url, previewAttachment.type).startsWith('image/') ? (
                                <Image size={20} />
                            ) : (
                                <FileText size={20} />
                            )}
                        </div>
                        <div className="min-w-0">
                            <h3 className="font-bold text-text truncate text-sm md:text-base">{previewAttachment.name}</h3>
                            <p className="text-[0.7rem] text-text-muted capitalize">
                                {getFileType(previewAttachment.url, previewAttachment.type).replace('application/', '').replace('image/', '')} File
                            </p>
                        </div>
                    </div>
                    
                    <div className="flex items-center gap-2">
                        {/* Download button */}
                        <button 
                            onClick={() => handleDownload(previewAttachment.url, previewAttachment.name)}
                            className="w-9 h-9 rounded-full hover:bg-muted border border-border/50 flex items-center justify-center text-text hover:text-primary transition-all"
                            title="Download"
                        >
                            <Download size={16} />
                        </button>
                        
                        {/* Open in new tab/fullscreen */}
                        <a 
                            href={previewAttachment.url}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="w-9 h-9 rounded-full hover:bg-muted border border-border/50 flex items-center justify-center text-text hover:text-primary transition-all"
                            title="Open in new window"
                        >
                            <Eye size={16} />
                        </a>
                        
                        {/* Close button */}
                        <button 
                            onClick={() => { setPreviewAttachment(null); setTextContent(null); setZoomScale(1); }}
                            className="w-9 h-9 rounded-full hover:bg-red-500/10 border border-transparent hover:border-red-500/20 flex items-center justify-center text-text-muted hover:text-red-500 transition-all"
                            title="Close"
                        >
                            <X size={18} />
                        </button>
                    </div>
                </div>

                {/* Content Area */}
                <div className="flex-1 overflow-auto p-6 flex flex-col items-center justify-center min-h-[300px] max-h-[70vh] bg-background/30 custom-scrollbar">
                    {(() => {
                        const fileType = getFileType(previewAttachment.url, previewAttachment.type);
                        
                        if (fileType.startsWith('image/')) {
                            return (
                                <div className="flex flex-col items-center justify-center gap-4 w-full h-full relative">
                                    {/* Image controls for zooming */}
                                    <div className="flex items-center gap-2 bg-card/90 border border-border rounded-full py-1.5 px-3 shadow-md z-10">
                                        <button 
                                            onClick={() => setZoomScale(prev => Math.max(0.5, prev - 0.25))}
                                            className="w-7 h-7 rounded-full hover:bg-muted flex items-center justify-center text-text font-bold text-xs"
                                        >
                                            -
                                        </button>
                                        <span className="text-xs font-semibold text-text min-w-[40px] text-center">
                                            {Math.round(zoomScale * 100)}%
                                        </span>
                                        <button 
                                            onClick={() => setZoomScale(prev => Math.min(3, prev + 0.25))}
                                            className="w-7 h-7 rounded-full hover:bg-muted flex items-center justify-center text-text font-bold text-xs"
                                        >
                                            +
                                        </button>
                                        <button 
                                            onClick={() => setZoomScale(1)}
                                            className="ml-1 text-[0.65rem] hover:text-primary font-bold text-text-muted uppercase tracking-wider px-2 py-0.5 rounded hover:bg-muted"
                                        >
                                            Reset
                                        </button>
                                    </div>
                                    
                                    <div className="flex-1 w-full flex items-center justify-center overflow-auto max-h-[55vh] rounded-2xl bg-black/5 dark:bg-white/5 border border-border/30 p-2">
                                        <img 
                                            src={previewAttachment.url} 
                                            alt={previewAttachment.name} 
                                            className="max-h-[50vh] max-w-full object-contain rounded-lg transition-transform duration-200 ease-out" 
                                            style={{ transform: `scale(${zoomScale})` }}
                                        />
                                    </div>
                                </div>
                            );
                        }
                        
                        if (fileType === 'application/pdf') {
                            return (
                                <div className="w-full h-full min-h-[50vh] flex flex-col">
                                    <iframe 
                                        src={previewAttachment.url} 
                                        className="w-full flex-1 rounded-2xl border border-border/80 bg-white" 
                                        title={previewAttachment.name} 
                                    />
                                </div>
                            );
                        }
                        
                        if (fileType.startsWith('text/') || ['text/plain', 'text/csv', 'text/html', 'application/json'].includes(fileType)) {
                            return (
                                <div className="w-full flex flex-col h-full gap-2">
                                    {loadingText ? (
                                        <div className="flex flex-col items-center justify-center p-12 gap-3">
                                            <div className="w-8 h-8 border-3 border-primary border-t-transparent rounded-full animate-spin"></div>
                                            <p className="text-xs text-text-muted font-medium">Loading text contents...</p>
                                        </div>
                                    ) : (
                                        <div className="w-full rounded-2xl border border-border overflow-hidden bg-card text-left flex flex-col flex-1">
                                            <div className="px-4 py-2 bg-muted/50 border-b border-border text-[0.65rem] font-bold text-text-muted flex justify-between items-center">
                                                <span>TEXT READER</span>
                                                <span>{textContent ? textContent.length : 0} characters</span>
                                            </div>
                                            <pre className="p-4 overflow-auto max-h-[50vh] text-[0.75rem] font-mono whitespace-pre text-text bg-background/50 flex-1 custom-scrollbar">
                                                {textContent || 'No content.'}
                                            </pre>
                                        </div>
                                    )}
                                </div>
                            );
                        }
                        
                        return (
                            <div className="flex flex-col items-center text-center p-8 max-w-md">
                                <div className="w-20 h-20 rounded-full bg-primary/10 text-primary flex items-center justify-center mb-5 border border-primary/20">
                                    <FileText size={36} />
                                </div>
                                <h4 className="font-bold text-text text-base mb-2">No Inline Preview Available</h4>
                                <p className="text-xs text-text-muted leading-relaxed mb-6">
                                    Previewing files of type <span className="font-mono text-primary bg-primary/5 px-1.5 py-0.5 rounded">{previewAttachment.type || 'unknown'}</span> is not supported in the browser. You can download the file to view it locally, or try opening it in a new window.
                                </p>
                                <div className="flex gap-3 w-full">
                                    <button 
                                        onClick={() => handleDownload(previewAttachment.url, previewAttachment.name)}
                                        className="flex-1 py-2.5 px-4 bg-primary text-white font-bold rounded-xl text-xs hover:bg-primary/95 transition-all shadow-md flex items-center justify-center gap-2"
                                    >
                                        <Download size={14} /> Download File
                                    </button>
                                    <a 
                                        href={previewAttachment.url}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        className="flex-1 py-2.5 px-4 bg-muted border border-border text-text hover:bg-muted/80 font-bold rounded-xl text-xs transition-all flex items-center justify-center gap-2"
                                    >
                                        <Eye size={14} /> Open in New Tab
                                    </a>
                                </div>
                            </div>
                        );
                    })()}
                </div>
            </div>
        </div>
      ,
        document.body
      )}

      <style>{`
        .custom-scrollbar::-webkit-scrollbar { width: 5px; }
        .custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
        .custom-scrollbar::-webkit-scrollbar-thumb { background: rgba(100, 100, 100, 0.2); border-radius: 10px; }
        .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgba(100, 100, 100, 0.4); }
      `}</style>
    </div>
  );
}
