'use client';

import { useState, useRef, useEffect, useCallback } from 'react';
import { useAppStore } from '@/lib/store';
import { t } from '@/lib/i18n';
import { mockConversations } from '@/lib/mock-data';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { ScrollArea } from '@/components/ui/scroll-area';
import {
  Search,
  ArrowLeft,
  Send,
  Paperclip,
  CheckCheck,
  Phone,
  PhoneCall,
  PhoneOff,
  MoreVertical,
  Loader2,
  LogIn,
  Image as ImageIcon,
  Smile,
  X,
  Mic,
  MicOff,
  Video,
  VideoOff,
} from 'lucide-react';
import { io, Socket } from 'socket.io-client';

// ─── Emoji data ───
const EMOJI_CATEGORIES = [
  { name: 'Smileys', emojis: ['😀','😃','😄','😁','😆','😅','🤣','😂','🙂','😊','😇','🥰','😍','🤩','😘','😗','😚','😙','🥲','😋','😛','😜','🤪','😝','🤑','🤗','🤭','🤫','🤔','🤐','🤨','😐','😑','😶','😏','😒','🙄','😬','😮‍💨','🤥','😌','😔','😪','🤤','😴','😷','🤒','🤕','🤢','🤮','🥵','🥶','🥴','😵','🤯','🤠','🥳','🥸','😎','🤓','🧐'] },
  { name: 'Gestures', emojis: ['👋','🤚','🖐️','✋','🖖','👌','🤌','🤏','✌️','🤞','🤟','🤘','🤙','👈','👉','👆','🖕','👇','☝️','👍','👎','✊','👊','🤛','🤜','👏','🙌','👐','🤲','🤝','🙏'] },
  { name: 'Hearts', emojis: ['❤️','🧡','💛','💚','💙','💜','🖤','🤍','🤎','💔','❣️','💕','💞','💓','💗','💖','💘','💝','💟','♥️'] },
  { name: 'Objects', emojis: ['🏠','🏡','🏢','🏣','🏤','🏥','🏦','🏨','🏩','🏪','🏫','🏬','🏭','🏗️','💼','📱','💻','🖥️','🖨️','⌨️','📸','🎥','📞','☎️','📺','📻','🎙️','⏰','🔔','🔑','🔒'] },
];

// ─── Helper: get initials from name ───
function getInitials(name: string): string {
  return name.split(' ').map((n) => n[0]).join('').toUpperCase().slice(0, 2);
}

// ─── Helper: avatar color from name ───
const avatarColors = ['bg-orange-500','bg-emerald-500','bg-violet-500','bg-rose-500','bg-cyan-500','bg-amber-500','bg-teal-500','bg-pink-500'];
function getAvatarColor(name: string): string {
  let hash = 0;
  for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
  return avatarColors[Math.abs(hash) % avatarColors.length];
}

// ─── Time formatting helpers ───
function formatMessageTime(dateString: string): string {
  return new Date(dateString).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}
function formatConversationTime(dateString: string): string {
  const diffMs = Date.now() - new Date(dateString).getTime();
  const mins = Math.floor(diffMs / 60000);
  if (mins < 1) return 'Just now';
  if (mins < 60) return `${mins}m ago`;
  const hrs = Math.floor(mins / 60);
  if (hrs < 24) return `${hrs}h ago`;
  const days = Math.floor(hrs / 24);
  if (days < 7) return `${days}d ago`;
  return new Date(dateString).toLocaleDateString([], { month: 'short', day: 'numeric' });
}
function getMessageDateLabel(dateString: string): string {
  const diffDays = Math.floor((Date.now() - new Date(dateString).getTime()) / 86400000);
  if (diffDays === 0) return 'Today';
  if (diffDays === 1) return 'Yesterday';
  return new Date(dateString).toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' });
}

// ─── Types ───
interface ApiConversation {
  id: string; name: string; phone: string | null; avatar: string | null;
  lastMessage: string; lastMessageTime: string; unreadCount: number;
}
interface ApiMessage {
  id: string; senderId: string; receiverId: string; content: string;
  messageType: string; isRead: boolean; createdAt: string;
  sender: { id: string; name: string; phone: string | null; avatar: string | null };
}
interface DisplayConversation {
  id: string; name: string; phone: string | null; avatar: string | null;
  lastMessage: string; lastMessageTime: string; unreadCount: number; online: boolean;
}
interface DisplayMessage {
  id: string; senderId: string; content: string; time: string;
  isMe: boolean; date: string; createdAt: string; messageType: string;
}
interface IncomingCallData {
  callerId: string; callerName: string; callType: 'audio' | 'video'; signalData?: any;
}

// ─── Call State ───
type CallState = 'idle' | 'calling' | 'ringing' | 'connected';

export default function MessagesModule() {
  const { language, openChatWith, setOpenChatWith, setCurrentSection, user } = useAppStore();
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedConversation, setSelectedConversation] = useState<DisplayConversation | null>(null);
  const [messageInput, setMessageInput] = useState('');
  const [messages, setMessages] = useState<DisplayMessage[]>([]);
  const [sending, setSending] = useState(false);
  const [allConversations, setAllConversations] = useState<DisplayConversation[]>([]);
  const [conversationsLoading, setConversationsLoading] = useState(false);
  const [messagesLoading, setMessagesLoading] = useState(false);
  const [conversationsError, setConversationsError] = useState<string | null>(null);
  const [messagesError, setMessagesError] = useState<string | null>(null);

  // Emoji & attachment state
  const [showEmoji, setShowEmoji] = useState(false);
  const [uploading, setUploading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const emojiRef = useRef<HTMLDivElement>(null);

  // Call state
  const [callState, setCallState] = useState<CallState>('idle');
  const [callType, setCallType] = useState<'audio' | 'video'>('audio');
  const [callPartner, setCallPartner] = useState<{ id: string; name: string } | null>(null);
  const [callDuration, setCallDuration] = useState(0);
  const [isMuted, setIsMuted] = useState(false);
  const [isVideoOff, setIsVideoOff] = useState(false);

  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const messageAreaRef = useRef<HTMLDivElement>(null);
  const processedChatIdRef = useRef<string | null>(null);
  const callTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // WebRTC refs
  const socketRef = useRef<Socket | null>(null);
  const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
  const localStreamRef = useRef<MediaStream | null>(null);
  const remoteAudioRef = useRef<HTMLAudioElement | null>(null);
  const localVideoRef = useRef<HTMLVideoElement | null>(null);
  const remoteVideoRef = useRef<HTMLVideoElement | null>(null);

  const ICE_SERVERS = [{ urls: 'stun:stun.l.google.com:19302' }, { urls: 'stun:stun1.l.google.com:19302' }];

  // ─── Socket.io connection for call signaling ───
  useEffect(() => {
    if (!user) return;
    const socket = io('/?XTransformPort=3005', {
      transports: ['websocket', 'polling'],
      forceNew: true,
      reconnection: true,
      reconnectionAttempts: 5,
      reconnectionDelay: 1000,
      timeout: 10000,
    });
    socketRef.current = socket;

    socket.on('connect', () => {
      socket.emit('register', { userId: user.id });
    });

    socket.on('incoming-call', (data: IncomingCallData) => {
      setCallState('ringing');
      setCallType(data.callType);
      setCallPartner({ id: data.callerId, name: data.callerName });
    });

    socket.on('call-accepted', async (data: { signalData: any }) => {
      if (peerConnectionRef.current) {
        try { await peerConnectionRef.current.setRemoteDescription(new RTCSessionDescription(data.signalData)); } catch (e) { console.error('Set remote desc error:', e); }
      }
    });

    socket.on('call-rejected', () => {
      endCall(false);
    });

    socket.on('call-ended', () => {
      endCall(false);
    });

    socket.on('ice-candidate', async (data: { candidate: any }) => {
      if (peerConnectionRef.current && data.candidate) {
        try { await peerConnectionRef.current.addIceCandidate(new RTCIceCandidate(data.candidate)); } catch (e) { console.error('Add ICE error:', e); }
      }
    });

    socket.on('offer', async (data: { offer: any }) => {
      if (peerConnectionRef.current) {
        try {
          await peerConnectionRef.current.setRemoteDescription(new RTCSessionDescription(data.offer));
          const answer = await peerConnectionRef.current.createAnswer();
          await peerConnectionRef.current.setLocalDescription(answer);
          socket.emit('answer', { receiverId: data.offer.from || callPartner?.id, answer: { ...answer, from: user.id } });
        } catch (e) { console.error('Answer error:', e); }
      }
    });

    socket.on('answer', async (data: { answer: any }) => {
      if (peerConnectionRef.current) {
        try { await peerConnectionRef.current.setRemoteDescription(new RTCSessionDescription(data.answer)); } catch (e) { console.error('Set answer error:', e); }
      }
    });

    socket.on('disconnect', () => {});

    return () => { socket.disconnect(); socketRef.current = null; };
  }, [user]);

  // ─── Create peer connection ───
  const createPeerConnection = useCallback((isInitiator: boolean, partnerId: string) => {
    const pc = new RTCPeerConnection({ iceServers: ICE_SERVERS });

    pc.onicecandidate = (event) => {
      if (event.candidate && socketRef.current) {
        socketRef.current.emit('ice-candidate', { receiverId: partnerId, candidate: event.candidate });
      }
    };

    pc.ontrack = (event) => {
      if (event.streams && event.streams[0]) {
        if (remoteAudioRef.current) {
          remoteAudioRef.current.srcObject = event.streams[0];
        }
        if (remoteVideoRef.current && callType === 'video') {
          remoteVideoRef.current.srcObject = event.streams[0];
        }
      }
    };

    pc.oniceconnectionstatechange = () => {
      if (pc.iceConnectionState === 'disconnected' || pc.iceConnectionState === 'failed') {
        endCall(false);
      }
    };

    peerConnectionRef.current = pc;
    return pc;
  }, [callType]);

  // ─── Start a call ───
  const startCall = useCallback(async (type: 'audio' | 'video', partnerId: string, partnerName: string) => {
    if (!user || !socketRef.current) return;
    try {
      const constraints = type === 'video' ? { audio: true, video: true } : { audio: true, video: false };
      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      localStreamRef.current = stream;

      if (localVideoRef.current && type === 'video') {
        localVideoRef.current.srcObject = stream;
      }

      const pc = createPeerConnection(true, partnerId);
      stream.getTracks().forEach((track) => pc.addTrack(track, stream));

      const offer = await pc.createOffer();
      await pc.setLocalDescription(offer);

      setCallState('calling');
      setCallType(type);
      setCallPartner({ id: partnerId, name: partnerName });

      socketRef.current.emit('call-user', {
        receiverId: partnerId,
        callType: type,
        callerName: user.name,
      });

      // Send offer via socket
      setTimeout(() => {
        if (socketRef.current) {
          socketRef.current.emit('offer', { receiverId: partnerId, offer: { ...offer, from: user.id } });
        }
      }, 500);

    } catch (err) {
      console.error('Failed to start call:', err);
      endCall(false);
    }
  }, [user, createPeerConnection]);

  // ─── Accept incoming call ───
  const acceptCall = useCallback(async () => {
    if (!user || !socketRef.current || !callPartner) return;
    try {
      const constraints = callType === 'video' ? { audio: true, video: true } : { audio: true, video: false };
      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      localStreamRef.current = stream;

      if (localVideoRef.current && callType === 'video') {
        localVideoRef.current.srcObject = stream;
      }

      const pc = createPeerConnection(false, callPartner.id);
      stream.getTracks().forEach((track) => pc.addTrack(track, stream));

      socketRef.current.emit('answer-call', { callerId: callPartner.id, signalData: {} });

      setCallState('connected');
      setCallDuration(0);
      callTimerRef.current = setInterval(() => setCallDuration((d) => d + 1), 1000);
    } catch (err) {
      console.error('Failed to accept call:', err);
      endCall(false);
    }
  }, [user, callPartner, callType, createPeerConnection]);

  // ─── Reject incoming call ───
  const rejectCall = useCallback(() => {
    if (socketRef.current && callPartner) {
      socketRef.current.emit('reject-call', { callerId: callPartner.id });
    }
    endCall(false);
  }, [callPartner]);

  // ─── End call ───
  const endCall = useCallback((notify = true) => {
    if (notify && socketRef.current && callPartner) {
      socketRef.current.emit('end-call', { otherUserId: callPartner.id });
    }
    if (localStreamRef.current) {
      localStreamRef.current.getTracks().forEach((t) => t.stop());
      localStreamRef.current = null;
    }
    if (peerConnectionRef.current) {
      peerConnectionRef.current.close();
      peerConnectionRef.current = null;
    }
    if (callTimerRef.current) { clearInterval(callTimerRef.current); callTimerRef.current = null; }
    setCallState('idle');
    setCallPartner(null);
    setCallDuration(0);
    setIsMuted(false);
    setIsVideoOff(false);
  }, [callPartner]);

  // ─── Toggle mute ───
  const toggleMute = useCallback(() => {
    if (localStreamRef.current) {
      localStreamRef.current.getAudioTracks().forEach((t) => { t.enabled = !t.enabled; });
      setIsMuted((m) => !m);
    }
  }, []);

  // ─── Toggle video ───
  const toggleVideo = useCallback(() => {
    if (localStreamRef.current) {
      localStreamRef.current.getVideoTracks().forEach((t) => { t.enabled = !t.enabled; });
      setIsVideoOff((v) => !v);
    }
  }, []);

  // ─── Format duration ───
  const formatDuration = (secs: number) => {
    const m = Math.floor(secs / 60).toString().padStart(2, '0');
    const s = (secs % 60).toString().padStart(2, '0');
    return `${m}:${s}`;
  };

  // ─── API Conversation converters ───
  const toDisplayConversation = useCallback((conv: ApiConversation): DisplayConversation => ({
    id: conv.id, name: conv.name, phone: conv.phone, avatar: conv.avatar,
    lastMessage: conv.lastMessage, lastMessageTime: conv.lastMessageTime,
    unreadCount: conv.unreadCount, online: false,
  }), []);

  const mockToDisplayConversation = useCallback((conv: (typeof mockConversations)[number]): DisplayConversation => ({
    id: conv.id, name: conv.name, phone: null, avatar: conv.avatar,
    lastMessage: conv.lastMessage, lastMessageTime: new Date().toISOString(),
    unreadCount: conv.unread, online: conv.online,
  }), []);

  const toDisplayMessage = useCallback((msg: ApiMessage): DisplayMessage => ({
    id: msg.id, senderId: msg.senderId, content: msg.content,
    time: formatMessageTime(msg.createdAt), isMe: user ? msg.senderId === user.id : false,
    date: getMessageDateLabel(msg.createdAt), createdAt: msg.createdAt,
    messageType: msg.messageType || 'text',
  }), [user]);

  // ─── Fetch conversations from API ───
  const fetchConversations = useCallback(async () => {
    if (!user) return;
    setConversationsLoading(true);
    setConversationsError(null);
    try {
      const res = await fetch(`/api/messages?userId=${user.id}`);
      if (!res.ok) throw new Error('Failed to fetch conversations');
      const data = await res.json();
      setAllConversations((data.conversations as ApiConversation[]).map(toDisplayConversation));
    } catch (err) {
      setConversationsError(err instanceof Error ? err.message : 'Failed to load conversations');
    } finally { setConversationsLoading(false); }
  }, [user, toDisplayConversation]);

  // ─── Fetch messages for a conversation ───
  const fetchMessages = useCallback(async (otherUserId: string) => {
    if (!user) return;
    setMessagesLoading(true);
    setMessagesError(null);
    try {
      const res = await fetch(`/api/messages/${otherUserId}?currentUserId=${user.id}`);
      if (!res.ok) throw new Error('Failed to fetch messages');
      const data = await res.json();
      setMessages((data.messages as ApiMessage[]).map(toDisplayMessage));
    } catch (err) {
      setMessagesError(err instanceof Error ? err.message : 'Failed to load messages');
    } finally { setMessagesLoading(false); }
  }, [user, toDisplayMessage]);

  // ─── Load conversations on mount ───
  useEffect(() => {
    if (user) { fetchConversations(); }
    else { setAllConversations(mockConversations.map(mockToDisplayConversation)); }
  }, [user, fetchConversations, mockToDisplayConversation]);

  // ─── Handle navigation from Contact Owner button ───
  useEffect(() => {
    if (!openChatWith) return;
    if (processedChatIdRef.current === openChatWith.id) return;
    processedChatIdRef.current = openChatWith.id;
    const chatTarget = { ...openChatWith };
    const timer = setTimeout(() => {
      const existingConv = allConversations.find((c) => c.id === chatTarget.id);
      if (existingConv) {
        setSelectedConversation(existingConv);
        if (user) fetchMessages(existingConv.id);
      } else {
        const newConv: DisplayConversation = {
          id: chatTarget.id, name: chatTarget.name, phone: chatTarget.phone || null,
          avatar: null, lastMessage: chatTarget.listingTitle ? `Regarding: ${chatTarget.listingTitle}` : 'Start a conversation',
          lastMessageTime: new Date().toISOString(), unreadCount: 0, online: false,
        };
        setAllConversations((prev) => [newConv, ...prev]);
        setSelectedConversation(newConv);
        setMessages([]);
      }
      setOpenChatWith(null);
    }, 0);
    return () => clearTimeout(timer);
  }, [openChatWith, allConversations, setOpenChatWith, user, fetchMessages]);

  const filteredConversations = allConversations.filter((c) =>
    c.name.toLowerCase().includes(searchQuery.toLowerCase()) || c.lastMessage.toLowerCase().includes(searchQuery.toLowerCase())
  );

  const scrollToBottom = useCallback(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, []);
  useEffect(() => { scrollToBottom(); }, [messages, selectedConversation, scrollToBottom]);
  useEffect(() => { if (selectedConversation) setTimeout(() => inputRef.current?.focus(), 100); }, [selectedConversation]);

  const handleSelectConversation = useCallback((conv: DisplayConversation) => {
    setSelectedConversation(conv);
    if (user) fetchMessages(conv.id);
  }, [user, fetchMessages]);

  // ─── Send text message ───
  const handleSendMessage = async () => {
    if (!messageInput.trim() || !user || !selectedConversation) return;
    setSending(true);
    try {
      const res = await fetch('/api/messages', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ senderId: user.id, receiverId: selectedConversation.id, content: messageInput.trim() }),
      });
      if (!res.ok) throw new Error('Failed to send');
      setMessageInput('');
      setShowEmoji(false);
      await fetchMessages(selectedConversation.id);
      await fetchConversations();
    } catch (err) { console.error('Send error:', err); }
    finally { setSending(false); }
  };

  // ─── Send file (image/video) ───
  const handleFileUpload = async (file: File) => {
    if (!user || !selectedConversation) return;
    setUploading(true);
    try {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('category', 'message');
      const uploadRes = await fetch('/api/upload', { method: 'POST', body: formData });
      if (!uploadRes.ok) throw new Error('Upload failed');
      const uploadData = await uploadRes.json();
      const fileUrl = uploadData.url;
      const msgType = file.type.startsWith('video/') ? 'video' : 'image';
      const content = msgType === 'video' ? `📹 Video: ${fileUrl}` : `🖼️ Image: ${fileUrl}`;

      const res = await fetch('/api/messages', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ senderId: user.id, receiverId: selectedConversation.id, content, messageType: msgType }),
      });
      if (!res.ok) throw new Error('Failed to send');
      await fetchMessages(selectedConversation.id);
      await fetchConversations();
    } catch (err) { console.error('File upload error:', err); }
    finally { setUploading(false); }
  };

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

  // Close emoji picker when clicking outside
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (showEmoji && emojiRef.current && !emojiRef.current.contains(e.target as Node)) {
        setShowEmoji(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [showEmoji]);

  const handleBack = () => {
    setSelectedConversation(null);
    setMessages([]);
    if (user) fetchConversations();
  };

  // ─── Render file content in messages ───
  const renderMessageContent = (msg: DisplayMessage) => {
    if (msg.messageType === 'image' || msg.content.startsWith('🖼️ Image: ')) {
      const url = msg.content.replace('🖼️ Image: ', '');
      return (
        <div className="space-y-1">
          <img src={url} alt="Shared image" className="max-w-full rounded-lg max-h-48 object-cover cursor-pointer" onClick={() => window.open(url, '_blank')} />
        </div>
      );
    }
    if (msg.messageType === 'video' || msg.content.startsWith('📹 Video: ')) {
      const url = msg.content.replace('📹 Video: ', '');
      return (
        <div className="space-y-1">
          <video src={url} controls className="max-w-full rounded-lg max-h-48" preload="metadata" />
        </div>
      );
    }
    return <p className="text-[13px] leading-relaxed whitespace-pre-wrap break-words">{msg.content}</p>;
  };

  // ─── Call overlay UI ───
  const renderCallOverlay = () => {
    if (callState === 'idle') return null;

    // Ringing (incoming call)
    if (callState === 'ringing') {
      return (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm">
          <div className="flex flex-col items-center gap-6 rounded-3xl bg-card p-8 shadow-2xl w-72">
            <div className="relative">
              <Avatar className="h-20 w-20">
                <AvatarFallback className={`${getAvatarColor(callPartner?.name || '')} text-2xl font-bold text-white`}>
                  {getInitials(callPartner?.name || '?')}
                </AvatarFallback>
              </Avatar>
              <span className="absolute -bottom-1 -right-1 h-5 w-5 rounded-full border-2 border-card bg-emerald-500" />
            </div>
            <div className="text-center">
              <h3 className="text-lg font-semibold">{callPartner?.name}</h3>
              <p className="text-sm text-muted-foreground mt-1">
                {callType === 'video'
                  ? (language === 'bn' ? 'ভিডিও কল আসছে...' : 'Incoming video call...')
                  : (language === 'bn' ? 'ভয়েস কল আসছে...' : 'Incoming voice call...')}
              </p>
            </div>
            <div className="flex items-center gap-6">
              <Button onClick={rejectCall} className="h-14 w-14 rounded-full bg-red-500 hover:bg-red-600 text-white shadow-lg">
                <PhoneOff className="h-6 w-6" />
              </Button>
              <Button onClick={acceptCall} className="h-14 w-14 rounded-full bg-emerald-500 hover:bg-emerald-600 text-white shadow-lg">
                <PhoneCall className="h-6 w-6" />
              </Button>
            </div>
          </div>
        </div>
      );
    }

    // Calling or Connected
    return (
      <div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-gradient-to-b from-card to-background">
        {/* Video elements (hidden for audio, visible for video) */}
        <audio ref={remoteAudioRef} autoPlay className="hidden" />
        {callType === 'video' && (
          <div className="absolute inset-0">
            <video ref={remoteVideoRef} autoPlay playsInline className="h-full w-full object-cover" />
            <video ref={localVideoRef} autoPlay playsInline muted className="absolute bottom-24 right-4 h-32 w-24 rounded-xl border-2 border-white/30 object-cover shadow-lg" />
          </div>
        )}

        <div className={`flex flex-col items-center gap-4 ${callType === 'video' ? 'absolute top-12' : ''}`}>
          {callType === 'audio' && (
            <div className="relative">
              <Avatar className={`h-24 w-24 ${callState === 'calling' ? 'animate-pulse' : ''}`}>
                <AvatarFallback className={`${getAvatarColor(callPartner?.name || '')} text-3xl font-bold text-white`}>
                  {getInitials(callPartner?.name || '?')}
                </AvatarFallback>
              </Avatar>
            </div>
          )}
          <h3 className="text-xl font-semibold text-foreground drop-shadow">{callPartner?.name}</h3>
          <p className="text-sm text-muted-foreground">
            {callState === 'calling'
              ? (language === 'bn' ? 'কল হচ্ছে...' : 'Calling...')
              : formatDuration(callDuration)}
          </p>
        </div>

        {/* Call controls */}
        <div className={`flex items-center gap-4 ${callType === 'video' ? 'absolute bottom-12' : 'mt-8'}`}>
          <Button onClick={toggleMute} variant="outline" className={`h-12 w-12 rounded-full ${isMuted ? 'bg-red-100 text-red-500 border-red-300' : ''}`}>
            {isMuted ? <MicOff className="h-5 w-5" /> : <Mic className="h-5 w-5" />}
          </Button>
          {callType === 'video' && (
            <Button onClick={toggleVideo} variant="outline" className={`h-12 w-12 rounded-full ${isVideoOff ? 'bg-red-100 text-red-500 border-red-300' : ''}`}>
              {isVideoOff ? <VideoOff className="h-5 w-5" /> : <Video className="h-5 w-5" />}
            </Button>
          )}
          <Button onClick={() => endCall(true)} className="h-14 w-14 rounded-full bg-red-500 hover:bg-red-600 text-white shadow-lg">
            <PhoneOff className="h-6 w-6" />
          </Button>
        </div>
      </div>
    );
  };

  // ─── Conversation List View ───
  const renderConversationList = () => (
    <div className="flex h-full flex-col">
      <div className="border-b bg-background px-4 py-3">
        <div className="flex items-center gap-2">
          <Button variant="ghost" size="icon" onClick={() => setCurrentSection('home')} className="h-9 w-9 shrink-0">
            <ArrowLeft className="h-5 w-5" />
          </Button>
          <div>
            <h1 className="text-xl font-bold text-foreground">{t('msg.title', language)}</h1>
            <p className="mt-0.5 text-xs text-muted-foreground">{filteredConversations.length} {language === 'bn' ? 'কথোপকথন' : 'conversations'}</p>
          </div>
        </div>
      </div>

      <div className="border-b px-4 py-3">
        <div className="relative">
          <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <Input placeholder={t('msg.search', language)} value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} className="pl-9 h-9 bg-muted/50 border-0 focus-visible:ring-1 focus-visible:ring-primary/50" />
        </div>
      </div>

      {!user && (
        <div className="border-b bg-muted/30 px-4 py-3">
          <div className="flex items-center gap-3">
            <LogIn className="h-5 w-5 shrink-0 text-muted-foreground" />
            <div className="flex-1">
              <p className="text-xs font-medium">{language === 'bn' ? 'মেসেজ পাঠাতে লগইন করুন' : 'Log in to send messages'}</p>
              <p className="text-[11px] text-muted-foreground">{language === 'bn' ? 'মেসেজ সংরক্ষণ করতে লগইন করুন' : 'Log in to save messages'}</p>
            </div>
          </div>
        </div>
      )}

      {conversationsLoading && (
        <div className="flex items-center justify-center py-12">
          <Loader2 className="h-6 w-6 animate-spin text-primary" />
          <span className="ml-2 text-sm text-muted-foreground">{language === 'bn' ? 'লোড হচ্ছে...' : 'Loading...'}</span>
        </div>
      )}

      {!conversationsLoading && !conversationsError && (
        <ScrollArea className="flex-1">
          <div className="divide-y">
            {filteredConversations.map((conv) => (
              <button key={conv.id} onClick={() => handleSelectConversation(conv)} className="flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-accent/50 active:bg-accent">
                <div className="relative shrink-0">
                  <Avatar className="h-12 w-12">
                    <AvatarFallback className={`${getAvatarColor(conv.name)} text-sm font-semibold text-white`}>{getInitials(conv.name)}</AvatarFallback>
                  </Avatar>
                  {conv.online && <span className="absolute bottom-0 right-0 h-3.5 w-3.5 rounded-full border-2 border-background bg-emerald-500" />}
                </div>
                <div className="min-w-0 flex-1">
                  <div className="flex items-center justify-between gap-2">
                    <span className={`truncate text-sm ${conv.unreadCount > 0 ? 'font-bold' : 'font-medium text-foreground/80'}`}>{conv.name}</span>
                    <span className="shrink-0 text-[11px] text-muted-foreground">{formatConversationTime(conv.lastMessageTime)}</span>
                  </div>
                  <div className="mt-0.5 flex items-center justify-between gap-2">
                    <p className="truncate text-xs text-muted-foreground">{conv.lastMessage}</p>
                    {conv.unreadCount > 0 && <Badge className="h-5 min-w-5 shrink-0 rounded-full bg-primary px-1.5 text-[10px] font-bold text-primary-foreground">{conv.unreadCount}</Badge>}
                  </div>
                </div>
              </button>
            ))}
            {filteredConversations.length === 0 && (
              <div className="flex flex-col items-center justify-center py-16"><Search className="h-10 w-10 text-muted-foreground/40" /><p className="mt-3 text-sm text-muted-foreground">{t('common.noResults', language)}</p></div>
            )}
          </div>
        </ScrollArea>
      )}
    </div>
  );

  // ─── Chat View ───
  const renderChatView = () => {
    const conv = selectedConversation!;
    const groupedMessages: { date: string; messages: DisplayMessage[] }[] = [];
    let currentDate = '';
    messages.forEach((msg) => {
      if (msg.date !== currentDate) { currentDate = msg.date; groupedMessages.push({ date: currentDate, messages: [msg] }); }
      else { groupedMessages[groupedMessages.length - 1].messages.push(msg); }
    });

    return (
      <div className="flex h-full flex-col">
        {/* Chat Header */}
        <div className="flex items-center gap-3 border-b bg-background px-3 py-2.5 shadow-sm">
          <Button variant="ghost" size="icon" onClick={handleBack} className="h-9 w-9 shrink-0"><ArrowLeft className="h-5 w-5" /></Button>
          <div className="relative shrink-0">
            <Avatar className="h-10 w-10">
              <AvatarFallback className={`${getAvatarColor(conv.name)} text-xs font-semibold text-white`}>{getInitials(conv.name)}</AvatarFallback>
            </Avatar>
            {conv.online && <span className="absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-background bg-emerald-500" />}
          </div>
          <div className="min-w-0 flex-1">
            <h2 className="truncate text-sm font-semibold text-foreground">{conv.name}</h2>
            <p className="text-[11px] text-muted-foreground">{conv.phone || (language === 'bn' ? 'ফোন নম্বর নেই' : 'No phone')}</p>
          </div>
          <div className="flex items-center gap-1">
            {user && (
              <>
                <Button variant="ghost" size="icon" className="h-9 w-9 text-muted-foreground" onClick={() => startCall('audio', conv.id, conv.name)} title="Voice call">
                  <Phone className="h-4 w-4" />
                </Button>
                <Button variant="ghost" size="icon" className="h-9 w-9 text-muted-foreground" onClick={() => startCall('video', conv.id, conv.name)} title="Video call">
                  <Video className="h-4 w-4" />
                </Button>
              </>
            )}
            <Button variant="ghost" size="icon" className="h-9 w-9 text-muted-foreground"><MoreVertical className="h-4 w-4" /></Button>
          </div>
        </div>

        {/* Messages Area */}
        <div ref={messageAreaRef} className="flex-1 overflow-y-auto bg-muted/30 px-4 py-4" style={{ scrollbarWidth: 'thin' }}>
          {messagesLoading && (
            <div className="flex items-center justify-center py-12"><Loader2 className="h-5 w-5 animate-spin text-primary" /><span className="ml-2 text-xs text-muted-foreground">{language === 'bn' ? 'মেসেজ লোড হচ্ছে...' : 'Loading messages...'}</span></div>
          )}
          {!messagesLoading && !messagesError && messages.length === 0 && (
            <div className="flex flex-col items-center justify-center py-12 text-center">
              <p className="text-xs text-muted-foreground">{language === 'bn' ? 'কোনো মেসেজ নেই। প্রথম মেসেজ পাঠান!' : 'No messages yet. Start the conversation!'}</p>
            </div>
          )}
          {!messagesLoading && !messagesError && groupedMessages.map((group) => (
            <div key={group.date}>
              <div className="my-4 flex justify-center"><span className="rounded-full bg-muted px-3 py-1 text-[11px] font-medium text-muted-foreground shadow-sm">{group.date}</span></div>
              {group.messages.map((msg, idx) => {
                const showAvatar = !msg.isMe && (idx === group.messages.length - 1 || group.messages[idx + 1]?.isMe);
                return (
                  <div key={msg.id} className={`flex ${msg.isMe ? 'justify-end' : 'justify-start'} mb-1`}>
                    <div className={`flex items-end gap-2 max-w-[80%] ${msg.isMe ? 'flex-row-reverse' : 'flex-row'}`}>
                      <div className="w-7 shrink-0">
                        {showAvatar && <Avatar className="h-7 w-7"><AvatarFallback className={`${getAvatarColor(conv.name)} text-[9px] font-semibold text-white`}>{getInitials(conv.name)}</AvatarFallback></Avatar>}
                      </div>
                      <div className={`rounded-2xl px-3.5 py-2 shadow-sm ${msg.isMe ? 'rounded-br-md bg-primary text-primary-foreground' : 'rounded-bl-md bg-card text-card-foreground border border-border/50'}`}>
                        {renderMessageContent(msg)}
                        <div className={`mt-1 flex items-center gap-1 ${msg.isMe ? 'justify-end' : 'justify-start'}`}>
                          <span className={`text-[10px] ${msg.isMe ? 'text-primary-foreground/60' : 'text-muted-foreground'}`}>{msg.time}</span>
                          {msg.isMe && <CheckCheck className="h-3 w-3 text-primary-foreground/60" />}
                        </div>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          ))}
          <div ref={messagesEndRef} />
        </div>

        {/* Emoji Picker */}
        {showEmoji && (
          <div ref={emojiRef} className="border-t bg-background max-h-52 overflow-y-auto">
            <div className="flex items-center justify-between px-3 py-2 border-b sticky top-0 bg-background z-10">
              <div className="flex gap-1">
                {EMOJI_CATEGORIES.map((cat) => (
                  <button key={cat.name} onClick={() => {
                    const el = document.getElementById(`emoji-cat-${cat.name}`);
                    el?.scrollIntoView({ behavior: 'smooth' });
                  }} className="text-[10px] px-2 py-1 rounded-full hover:bg-accent text-muted-foreground">
                    {cat.name}
                  </button>
                ))}
              </div>
              <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setShowEmoji(false)}><X className="h-3.5 w-3.5" /></Button>
            </div>
            {EMOJI_CATEGORIES.map((cat) => (
              <div key={cat.name} id={`emoji-cat-${cat.name}`} className="px-3 py-1.5">
                <p className="text-[10px] font-medium text-muted-foreground mb-1">{cat.name}</p>
                <div className="flex flex-wrap gap-0.5">
                  {cat.emojis.map((emoji, i) => (
                    <button key={i} onClick={() => { setMessageInput((prev) => prev + emoji); inputRef.current?.focus(); }} className="h-8 w-8 flex items-center justify-center text-lg hover:bg-accent rounded transition-colors active:scale-90">{emoji}</button>
                  ))}
                </div>
              </div>
            ))}
          </div>
        )}

        {/* Hidden file input */}
        <input type="file" ref={fileInputRef} className="hidden" accept="image/*,video/*" onChange={(e) => {
          const file = e.target.files?.[0];
          if (file) handleFileUpload(file);
          e.target.value = '';
        }} />

        {/* Input Area */}
        <div className="border-t bg-background px-3 py-2.5">
          {!user ? (
            <div className="flex items-center justify-center gap-2 py-2">
              <LogIn className="h-4 w-4 text-muted-foreground" />
              <p className="text-xs text-muted-foreground">{language === 'bn' ? 'মেসেজ পাঠাতে লগইন করুন' : 'Log in to send messages'}</p>
            </div>
          ) : (
            <div className="flex items-end gap-1.5">
              {/* Attach button */}
              <Button variant="ghost" size="icon" className="h-9 w-9 shrink-0 text-muted-foreground hover:text-primary" onClick={() => fileInputRef.current?.click()} disabled={uploading}>
                {uploading ? <Loader2 className="h-5 w-5 animate-spin" /> : <Paperclip className="h-5 w-5" />}
              </Button>

              <div className="relative min-w-0 flex-1">
                <Input
                  ref={inputRef}
                  placeholder={uploading ? (language === 'bn' ? 'আপলোড হচ্ছে...' : 'Uploading...') : t('msg.typeMessage', language)}
                  value={messageInput}
                  onChange={(e) => setMessageInput(e.target.value)}
                  onKeyDown={handleKeyDown}
                  disabled={sending || uploading}
                  className="h-10 rounded-full border-muted bg-muted/50 pr-10 text-sm focus-visible:ring-primary/50"
                />
                {/* Emoji button */}
                <Button variant="ghost" size="icon" className="absolute right-1 top-1/2 h-7 w-7 -translate-y-1/2 text-muted-foreground hover:text-primary" onClick={() => setShowEmoji(!showEmoji)}>
                  <Smile className="h-4 w-4" />
                </Button>
              </div>

              {/* Send / Image / Video quick buttons */}
              {messageInput.trim() ? (
                <Button size="icon" onClick={handleSendMessage} disabled={sending} className="h-10 w-10 shrink-0 rounded-full bg-primary text-primary-foreground shadow-md hover:bg-primary/90 disabled:opacity-50">
                  {sending ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send className="h-4 w-4" />}
                </Button>
              ) : (
                <div className="flex items-center gap-1">
                  <Button variant="ghost" size="icon" className="h-9 w-9 shrink-0 text-muted-foreground hover:text-primary" onClick={() => { const input = document.createElement('input'); input.type = 'file'; input.accept = 'image/*'; input.onchange = (e) => { const f = (e.target as HTMLInputElement).files?.[0]; if (f) handleFileUpload(f); }; input.click(); }} disabled={uploading}>
                    <ImageIcon className="h-5 w-5" />
                  </Button>
                </div>
              )}
            </div>
          )}
        </div>
      </div>
    );
  };

  return (
    <div className="flex h-[calc(100vh-8rem)] flex-col overflow-hidden relative">
      {selectedConversation ? renderChatView() : renderConversationList()}
      {renderCallOverlay()}
    </div>
  );
}
