"use client";
import { useState, useEffect, useMemo } from 'react';
import { useAuth } from '@/contexts/auth-context';
import { useContacts } from '@/contexts/contacts-context';
import { useGroups } from '@/contexts/groups-context';
import { useSettings } from '@/contexts/settings-context';
import { useFirebase } from '@/contexts/firebase-context';
import { Button } from './ui/button';
import { Cog, LogOut, Users, Sparkles, Globe, UserPlus, Search, X, Loader2, MoreVertical, Ban, Check, Mail, LayoutGrid, Phone, Settings, User } from 'lucide-react';
import type { ChatRecipient, Contact, Group, User as UserType, ChatRequest, GroupInvitation } from '@/lib/types';
import { Input } from './ui/input';
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
import { Badge } from './ui/badge';
import { Separator } from './ui/separator';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './ui/dropdown-menu';
import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs';
import { UserListItem } from './user-list-item';
import { onValue, ref } from 'firebase/database';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
const loodaAssistant: ChatRecipient = {
uid: 'looda-assistant',
displayName: 'Looda',
isBot: true,
photoURL: 'https://api.dicebear.com/8.x/bottts/svg?seed=Looda'
}
const khaloushAssistant: ChatRecipient = {
uid: 'khaloush-assistant',
displayName: 'Khaloush',
isBot: true,
photoURL: 'https://api.dicebear.com/8.x/bottts/svg?seed=Khaloush'
}
const GroupListItem = ({ group, onSelectRecipient }: { group: Group, onSelectRecipient: (recipient: ChatRecipient) => void }) => {
const { playSound, t } = useSettings();
const groupType = group.info.type || 'general';
return (
)};
const ChatRequestItem = ({ request, onAccept, onDecline }: {
request: ChatRequest;
onAccept: (request: ChatRequest) => void;
onDecline: (request: ChatRequest, andBlock: boolean) => void;
}) => {
const { playSound, t } = useSettings();
return (
{request.displayName.charAt(0)}
{request.displayName}
@{request.publicId}
playSound('touch')}>
onDecline(request, false)}>{t('decline')}
onDecline(request, true)} className="text-destructive">
{t('declineAndBlock')}
);
};
const GroupInvitationItem = ({ invitation, onAccept, onDecline }: {
invitation: GroupInvitation;
onAccept: (invitation: GroupInvitation) => void;
onDecline: (invitation: GroupInvitation) => void;
}) => {
const { playSound, t } = useSettings();
return (
{invitation.groupName.charAt(0)}
{invitation.groupName}
{t('invitedBy', { name: invitation.invitedBy })}
);
};
export function UserList({
onSelectRecipient,
onOpenCreateGroup,
onOpenSettings,
onSignOut,
onViewProfile
}: {
onSelectRecipient: (recipient: ChatRecipient) => void,
onOpenCreateGroup: () => void,
onOpenSettings: () => void,
onSignOut: () => void,
onViewProfile: (user: UserType) => void
}) {
const { currentUser } = useAuth();
const { contacts, chatRequests, findUserByPublicId, sendChatRequest, acceptChatRequest, declineChatRequest } = useContacts();
const { groups, groupInvitations, acceptGroupInvitation, declineGroupInvitation } = useGroups();
const { rtdb } = useFirebase();
const { addToast, playSound, t } = useSettings();
const [searchTerm, setSearchTerm] = useState('');
const [searchResult, setSearchResult] = useState(null);
const [isSearching, setIsSearching] = useState(false);
const [onlineStatus, setOnlineStatus] = useState<{[key: string]: {isOnline: boolean, lastSeen: number}}>({});
const router = useRouter();
useEffect(() => {
if (!currentUser) return;
const presenceRef = ref(rtdb, 'presence');
const unsubscribe = onValue(presenceRef, (snapshot) => {
const data = snapshot.val() || {};
setOnlineStatus(data);
});
return () => unsubscribe();
}, [rtdb, currentUser]);
const contactsWithStatus = useMemo(() => {
return contacts.map(contact => ({
...contact,
isOnline: onlineStatus[contact.uid]?.isOnline,
}));
}, [contacts, onlineStatus]);
const handleSearch = async (e: React.KeyboardEvent) => {
if (e.key !== 'Enter' || !searchTerm.trim()) return;
playSound('touch');
const term = searchTerm.trim().toLowerCase();
setIsSearching(true);
setSearchResult(null);
if (term === currentUser?.publicId) {
addToast(t("youCantAddYourself"), { variant: "destructive" });
setIsSearching(false);
return;
}
const user = await findUserByPublicId(term);
setSearchResult(user || 'not_found');
setIsSearching(false);
};
const handleStartChat = async (user: UserType) => {
playSound('touch');
const isContact = contacts.some(c => c.uid === user.uid);
if (isContact) {
onSelectRecipient({ ...user, isGroup: false, uid: user.uid, displayName: user.displayName });
} else {
await sendChatRequest(user);
}
setSearchTerm('');
setSearchResult(null);
}
if (!currentUser) {
return null;
}
return (
{
setSearchTerm(e.target.value);
if (!e.target.value) setSearchResult(null);
}}
onKeyDown={handleSearch}
/>
{isSearching && (
)}
{searchResult && searchResult !== 'not_found' && (
{t('searchResult')}
)}
{searchResult === 'not_found' && (
{t('userNotFound')}
)}
playSound('touch')}>{t('chatsTab')}
playSound('touch')}>
{t('requestsTab')}
{(chatRequests.length + groupInvitations.length > 0) && {chatRequests.length + groupInvitations.length}}
{t('mainSection')}
{groups.length > 0 && (
<>
{t('groupsSection')}
{groups.map(group =>
)}
>
)}
{t('contactsSection')}
{contactsWithStatus.map(contact =>
)}
{contacts.length === 0 && !searchTerm &&
{t('noContacts')}
}
{(chatRequests.length > 0 || groupInvitations.length > 0) ? (
{groupInvitations.length > 0 && (
{t('groupInvitations')}
{groupInvitations.map(inv => (
))}
)}
{chatRequests.length > 0 && (
{t('chatRequests')}
{chatRequests.map(req => (
))}
)}
) : (
{t('noNewRequests')}
)}
);
}