/* eslint-disable @typescript-eslint/no-explicit-any */
'use client';
import React, { useState, useEffect, useCallback, memo, useMemo, useRef } from 'react';
import { useAtom } from 'jotai';
import { cn } from './utils';
import { ChatUser } from './types';
import Image from 'next/image';
import { Search, Filter, Plus } from 'lucide-react';
import { isMobileAtom, selectedUserAtom, chatDetailOpenAtom } from './store';

// Mock data for chat users
const mockChatUsers: ChatUser[] = [
  {
    id: '1',
    name: 'Sam Ahmad',
    lastMessage: 'Hello, how are you?',
    timestamp: '10:30 AM',
    unread: 2,
  },
  {
    id: '2',
    name: 'John Doe',
    lastMessage: 'When is the meeting?',
    timestamp: 'Yesterday',
  },
  {
    id: '3',
    name: 'Sarah Johnson',
    lastMessage: 'Thanks for the update!',
    timestamp: 'Monday',
  },
  {
    id: '4',
    name: 'Alex Williams',
    lastMessage: 'Check the latest report',
    timestamp: 'Jun 15',
    unread: 1,
  },
  {
    id: '5',
    name: 'Emily Davis',
    lastMessage: 'I appreciate your help',
    timestamp: 'Jun 10',
  },
];

// Status indicator component
const StatusIndicator = memo(({ status }: { status?: 'online' | 'away' | 'offline' }) => {
  if (!status || status === 'offline') return null;
  
  return (
    <span 
      className={cn(
        "absolute bottom-0 right-0 w-3 h-3 rounded-full border-2 border-white",
        status === 'online' ? "bg-green-500" : "bg-yellow-500"
      )}
      aria-label={`Status: ${status}`}
    />
  );
});

StatusIndicator.displayName = 'StatusIndicator';

// Individual chat user item - memoized to prevent unnecessary renders
const ChatUserItem = memo(({ 
  user, 
  isMobile, 
  onSelect,
  isActive = false
}: { 
  user: ChatUser; 
  isMobile: boolean; 
  onSelect: (user: ChatUser) => void;
  isActive?: boolean;
}) => {
  const handleClick = useCallback(() => {
    onSelect(user);
  }, [user, onSelect]);

  return (
    <div 
      className={cn(
        "flex items-center p-3 cursor-pointer relative",
        isMobile ? "space-x-4" : "space-x-3",
        isActive ? "bg-blue-50" : "hover:bg-gray-50",
        "transition-colors duration-150"
      )}
      onClick={handleClick}
      aria-selected={isActive}
      role="option"
    >
      <div className="relative">
        <div className={cn(
          "bg-gray-200 rounded-full flex items-center justify-center shadow-sm",
          isMobile ? "w-14 h-14" : "w-12 h-12"
        )}>
          {user.avatar ? (
            <div className="relative w-full h-full rounded-full overflow-hidden">
              <Image 
                src={user.avatar} 
                alt={user.name} 
                fill 
                className="object-cover"
                sizes={isMobile ? "56px" : "48px"}
                loading="lazy"
                fetchPriority="high"
              />
            </div>
          ) : (
            <span className={cn(
              "font-semibold text-gray-600",
              isMobile ? "text-xl" : "text-lg"
            )}>
              {user.name.charAt(0)}
            </span>
          )}
        </div>
        <StatusIndicator status="online" />
        {user.unread && (
          <div className={cn(
            "absolute bg-red-500 text-white text-xs rounded-full flex items-center justify-center",
            isMobile ? "-top-1 -right-1 w-6 h-6" : "-top-1 -right-1 w-5 h-5"
          )}>
            {user.unread}
          </div>
        )}
      </div>
      <div className="flex-1 min-w-0">
        <div className="flex justify-between items-baseline">
          <h3 className={cn(
            "font-medium truncate",
            user.unread ? "font-semibold" : "",
            isMobile && "text-base"
          )}>
            {user.name}
          </h3>
          <span className={cn(
            "text-gray-500",
            isMobile ? "text-sm" : "text-xs"
          )}>
            {user.timestamp}
          </span>
        </div>
        <p className={cn(
          user.unread ? "text-gray-900 font-medium" : "text-gray-500",
          "truncate",
          isMobile ? "text-sm mt-1" : "text-sm"
        )}>
          {user.lastMessage}
        </p>
      </div>
    </div>
  );
});

ChatUserItem.displayName = 'ChatUserItem';

interface ChatUserListProps {
  onSelectUser: (user: ChatUser) => void;
}

// Generate more users for pagination demonstration
const generateMoreUsers = (startIndex: number, count: number): ChatUser[] => {
  return Array.from({ length: count }, (_, i) => {
    const index = startIndex + i;
    return {
      id: `generated-${index}`,
      name: `User ${index}`,
      lastMessage: `This is message ${index} from generated user`,
      timestamp: i === 0 ? 'Now' : i < 5 ? 'Today' : `${i} days ago`,
      unread: i % 5 === 0 ? Math.floor(Math.random() * 5) + 1 : undefined
    };
  });
};

const ChatUserList: React.FC<ChatUserListProps> = ({ onSelectUser }) => {
  const [isMobile, setIsMobile] = useAtom(isMobileAtom);
  const [selectedUser, setSelectedUser] = useAtom(selectedUserAtom);
  const [, setChatDetailOpen] = useAtom(chatDetailOpenAtom);
  
  const [users, setUsers] = useState<ChatUser[]>(mockChatUsers);
  const [loading, setLoading] = useState(false);
  const [, setPage] = useState(1);
  const [searchTerm, setSearchTerm] = useState('');
  const [showFilters, setShowFilters] = useState(false);
  
  const observerRef = useRef<any>(null);
  const loadMoreRef = useRef<HTMLDivElement>(null);
  
  // Detect mobile screen size with debounce
  useEffect(() => {
    let timeoutId: NodeJS.Timeout;
    
    const handleResize = () => {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        setIsMobile(typeof window !== 'undefined' && window.innerWidth < 768);
      }, 100);
    };
    
    // Initial check
    handleResize();
    
    // Add event listener with passive option for better performance
    if (typeof window !== 'undefined') {
      window.addEventListener('resize', handleResize, { passive: true });
    }
    
    // Clean up on unmount
    return () => {
      if (typeof window !== 'undefined') {
        window.removeEventListener('resize', handleResize);
      }
      clearTimeout(timeoutId);
    };
  }, [setIsMobile]);
  
  // Filter users based on search term
  const filteredUsers = useMemo(() => {
    if (!searchTerm.trim()) return users;
    
    const normalizedSearchTerm = searchTerm.toLowerCase();
    return users.filter(user => 
      user.name.toLowerCase().includes(normalizedSearchTerm) || 
      user.lastMessage.toLowerCase().includes(normalizedSearchTerm)
    );
  }, [users, searchTerm]);
  
  // Function to load more users
  const loadMoreUsers = useCallback(() => {
    if (loading || users.length >= 100) return;
    
    setLoading(true);
    
    // Simulate API call with delay
    setTimeout(() => {
      const newUsers = generateMoreUsers(users.length, 10);
      setUsers(prev => [...prev, ...newUsers]);
      setPage(prev => prev + 1);
      setLoading(false);
    }, 500);
  }, [loading, users.length]);
  
  // Handle scrolling to load more content
  const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
    const target = e.currentTarget as HTMLDivElement;
    const bottom = 
      target.scrollHeight - target.scrollTop <= 
      target.clientHeight + 100;
      
    if (bottom && !loading && users.length < 100) {
      loadMoreUsers();
    }
  }, [loading, users.length, loadMoreUsers]);
  
  // Setup IntersectionObserver for infinite scrolling
  useEffect(() => {
    // Early return if loading or browser doesn't support IntersectionObserver
    if (loading || typeof window === 'undefined' || typeof window.IntersectionObserver === 'undefined') return;
    
    const options = {
      root: null,
      rootMargin: '0px',
      threshold: 0.1
    };
    
    const handleObserver = (entries: any[]) => {
      const target = entries[0];
      if (target.isIntersecting && !loading && users.length < 100) {
        loadMoreUsers();
      }
    };
    
    // Cleanup previous observer
    if (observerRef.current) {
      observerRef.current.disconnect();
    }
    
    // Create new observer
    observerRef.current = new window.IntersectionObserver(handleObserver, options);
    
    // Start observing
    if (loadMoreRef.current) {
      observerRef.current.observe(loadMoreRef.current);
    }
    
    // Cleanup on unmount or deps change
    return () => {
      if (observerRef.current) {
        observerRef.current.disconnect();
      }
    };
  }, [loading, users.length, loadMoreUsers]);
  
  // Optimized handler to select a user
  const handleSelectUser = useCallback((user: ChatUser) => {
    setSelectedUser(user);
    setChatDetailOpen(true);
    onSelectUser(user);
  }, [setSelectedUser, setChatDetailOpen, onSelectUser]);
  
  // Handle search input changes
  const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchTerm(e.target.value);
  }, []);

  return (
    <div className="h-full flex flex-col bg-white">
      <div className={cn(
        "border-b border-gray-200 shrink-0 shadow-sm",
        isMobile ? "p-4 flex items-center justify-between" : "p-4"
      )}>
        <div className="flex items-center justify-between w-full">
          <h2 className="text-lg font-semibold text-gray-900">Messages</h2>
          <div className="flex items-center space-x-2">
            <button 
              className="p-2 hover:bg-gray-100 rounded-full transition-colors"
              aria-label="Create new message"
            >
              <Plus size={20} className="text-gray-600" />
            </button>
            {isMobile && (
              <button 
                className="text-blue-500 text-sm font-medium"
                onClick={() => {
                  // TODO: Implement edit functionality
                  console.log('Edit button clicked');
                }}
              >
                Edit
              </button>
            )}
          </div>
        </div>
      </div>
      
      <div className="px-4 pt-3 pb-2">
        <div className="relative">
          <input
            type="text"
            placeholder="Search messages..."
            className="w-full pl-10 pr-4 py-2 bg-gray-100 border-0 rounded-full focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all duration-200 outline-none"
            value={searchTerm}
            onChange={handleSearchChange}
          />
          <Search size={18} className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500" />
          <button 
            className="absolute right-3 top-1/2 transform -translate-y-1/2 p-1 hover:bg-gray-200 rounded-full transition-colors"
            onClick={() => setShowFilters(!showFilters)}
            aria-label="Show filters"
          >
            <Filter size={18} className="text-gray-500" />
          </button>
        </div>
        
        {showFilters && (
          <div className="flex mt-2 space-x-2 overflow-x-auto pb-1">
            <button className="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm whitespace-nowrap">
              Unread (3)
            </button>
            <button className="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm whitespace-nowrap">
              Groups
            </button>
            <button className="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm whitespace-nowrap">
              Important
            </button>
          </div>
        )}
      </div>
      
      <div 
        className="flex-1 overflow-y-auto divide-y divide-gray-200"
        onScroll={handleScroll}
        role="listbox"
      >
        {filteredUsers.length > 0 ? (
          filteredUsers.map(user => (
            <ChatUserItem 
              key={user.id} 
              user={user} 
              isMobile={isMobile} 
              onSelect={handleSelectUser}
              isActive={selectedUser?.id === user.id}
            />
          ))
        ) : (
          <div className="p-8 text-center text-gray-500">
            <p>No messages found matching your search.</p>
          </div>
        )}
        
        <div ref={loadMoreRef} className="h-10 flex items-center justify-center">
          {loading && (
            <div className="p-4 text-center text-gray-500 flex items-center justify-center space-x-2">
              <div className="w-4 h-4 rounded-full border-2 border-t-transparent border-blue-500 animate-spin"></div>
              <span>Loading more...</span>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default memo(ChatUserList);
 