﻿/**
 * 消息列表页 MessageListScreen
 * 威友 - 消息列表
 * 
 * 【重构后】使用MessageManager架构
 * - 纯渲染组件，不直接管理数据
 * - 通过useMessageList hook获取数据
 * - 所有状态变更通过MessageManager统一处理
 * - 支持响应式双栏布局（桌面端）
 */

import React, { useState, useCallback, useEffect, useMemo, useRef } from 'react';
import {
  View,
  StyleSheet,
  TouchableOpacity,
  Pressable,
  Modal,
  RefreshControl,
  ActivityIndicator,
  Animated,
  Keyboard,
  BackHandler,
  Platform,
} from 'react-native';
import { FlashList, ListRenderItem } from '@shopify/flash-list';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { useRouter } from 'expo-router';
import { useIsFocused } from "expo-router/react-navigation";
import { useBottomTabBarHeight } from "expo-router/js-tabs";
import { MaterialCommunityIcons } from '@expo/vector-icons';
import {
  spacing,
  fontSizes,
  shadows,
  borderRadius,
  useAppColors,
  type AppColors,
} from '../../theme';
import { ConversationResponse, UserDTO, MessageResponse, extractTextFromSegments } from '../../types/dto';
import { formatTime as formatTimeUtil } from '../../utils/formatTime';
import { authService } from '../../services';
import { blurActiveElement } from '../../infrastructure/platform';
import { useUserStore, useAuthStore } from '../../stores';
// 【新架构】使用MessageManager hooks（会话列表数据源自 MessageManager 游标同步）
import {
  messageManager,
  useMessageListRefresh,
  useCreateConversation,
  useUnreadCount,
  useMarkAsRead,
  useMessageManagerConversations,
  useMessageStore,
} from '../../stores';
import { Avatar, Text, EmptyState, ResponsiveContainer, AppBackButton } from '../../components/common';
import { useResponsive, useBreakpointGTE } from '../../hooks';
import * as hrefs from '../../navigation/hrefs';
// 导入 ChatScreen 组件用于桌面端双栏布局
import { ChatScreen } from './ChatScreen';
import { ConversationListRow } from './components/ConversationListRow';
// 导入 NotificationsScreen 用于在内部显示
import { NotificationsScreen } from './NotificationsScreen';
// 导入扫码组件
import { SearchBar, SearchHeader, TabBar } from '../../components/business';
import { QRCodeScanner } from '../../components/business/QRCodeScanner';

// 系统通知会话特殊ID
const SYSTEM_MESSAGE_CHANNEL_ID = '-1';

// 搜索结果类型
type SearchResultType = 'conversation' | 'user';

interface SearchResultItem {
  type: SearchResultType;
  conversation?: ConversationResponse;
  user?: UserDTO;
  matchedMessages?: MessageResponse[];
}

/**
 * MessageListScreen - 纯渲染组件
 * 所有数据通过useMessageList hook获取
 * 支持响应式双栏布局
 */
export const MessageListScreen: React.FC = () => {
  const colors = useAppColors();
  const styles = useMemo(() => createMessageListStyles(colors), [colors]);
  const router = useRouter();
  const isFocused = useIsFocused();
  const insets = useSafeAreaInsets();
  // 在大屏幕模式下不使用 Bottom Tab Navigator，所以不需要 tabBarHeight
  const { isMobile } = useResponsive();
  let tabBarHeight = 0;
  try {
    tabBarHeight = useBottomTabBarHeight();
  } catch (e) {
    // 大屏幕模式下不在 Bottom Tab Navigator 中，会抛出错误，忽略即可
    tabBarHeight = 0;
  }
  const currentUserId = useAuthStore(state => state.currentUser?.id);
  const setMessageUnreadCount = useUserStore(state => state.setMessageUnreadCount);

  // 响应式布局
  const { isDesktop, isTablet, width } = useResponsive();
  const isWideScreen = useBreakpointGTE('lg');

  // 会话列表：MessageManager 统一游标拉取与合并，与已读/角标同源
  const {
    conversations: conversationList,
    isLoading,
    hasMore,
    loadMore,
    refresh,
  } = useMessageManagerConversations();

  // 使用 MessageManager 获取未读数和系统通知数
  const { totalUnreadCount, systemUnreadCount } = useUnreadCount();
  const lastSystemMessageAt = useMessageStore(state => state.lastSystemMessageAt);
  const systemMessageTime = lastSystemMessageAt ?? '';
  const { markAllAsRead, isMarking } = useMarkAsRead(null);

  // 【新架构】使用MessageManager的hook创建会话
  const { createConversation } = useCreateConversation();

  // 本地刷新状态（仅用于下拉刷新的UI显示）
  const [refreshing, setRefreshing] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);

  // 上拉加载更多
  const onEndReached = useCallback(async () => {
    if (isLoading || loadingMore || !hasMore) return;
    setLoadingMore(true);
    await loadMore();
    setLoadingMore(false);
  }, [isLoading, loadingMore, hasMore, loadMore]);

  // 搜索相关状态
  const [isSearchMode, setIsSearchMode] = useState(false);
  const [searchText, setSearchText] = useState('');
  const [searchResults, setSearchResults] = useState<SearchResultItem[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const [activeSearchTab, setActiveSearchTab] = useState<'chat' | 'user'>('chat');
  const [actionMenuVisible, setActionMenuVisible] = useState(false);

  useEffect(() => {
    if (actionMenuVisible) {
      blurActiveElement();
    }
  }, [actionMenuVisible]);
  const [scannerVisible, setScannerVisible] = useState(false);

  // 系统通知显示状态 - 用于在移动端显示通知页面
  const [showNotifications, setShowNotifications] = useState(false);

  // Stable callbacks to avoid inline arrows passed to child components
  const stableCloseNotifications = useCallback(() => setShowNotifications(false), []);
  const stableClearSelectedConversation = useCallback(() => setSelectedConversation(null), []);
  const stableCloseScanner = useCallback(() => setScannerVisible(false), []);

  // 系统消息会话对象（用于选中状态）
  const systemMessageConversation: ConversationResponse = useMemo(() => ({
    id: SYSTEM_MESSAGE_CHANNEL_ID,
    type: 'private',
    last_seq: 0,
    last_message: {
      id: '0',
      conversation_id: SYSTEM_MESSAGE_CHANNEL_ID,
      sender_id: 'system',
      seq: 0,
      segments: [{ type: 'text', data: { text: '系统通知' } }],
      status: 'normal',
      created_at: systemMessageTime,
    },
    last_message_at: systemMessageTime,
    unread_count: systemUnreadCount,
    participants: [],
    created_at: systemMessageTime,
    updated_at: systemMessageTime,
  }), [systemUnreadCount, systemMessageTime]);

  // 动画值
  const [scaleAnims] = useState(() =>
    Array.from({ length: 20 }, () => new Animated.Value(1))
  );

  // 【桌面端双栏布局】选中会话的状态
  const [selectedConversation, setSelectedConversation] = useState<ConversationResponse | null>(null);

  // 计算侧边栏宽度（桌面端）
  const sidebarWidth = useMemo(() => {
    if (width >= 1440) return 380;
    if (width >= 1280) return 340;
    if (width >= 1024) return 320;
    return 280;
  }, [width]);

  // 给底部列表预留安全空间，避免被 TabBar 遮挡导致最后几项无法完整滑出
  // TabBar 悬浮：高度 64 + 浮动间距 12*2 = 88
  const listBottomInset = useMemo(() => {
    if (isWideScreen) return spacing.lg;
    const FLOATING_TAB_BAR_HEIGHT = 64 + 24; // TabBar高度 + 上下浮动间距
    return FLOATING_TAB_BAR_HEIGHT + insets.bottom + spacing.md;
  }, [isWideScreen, insets.bottom]);

  // 初始化MessageManager（仅首次），焦点时轻量刷新会话列表
  useEffect(() => {
    messageManager.initialize();
  }, []);

  useMessageListRefresh();

  // 同步未读数到userStore（用于TabBar角标显示）
  useEffect(() => {
    setMessageUnreadCount(totalUnreadCount + systemUnreadCount);
  }, [totalUnreadCount, systemUnreadCount, setMessageUnreadCount]);

  // 屏幕失去焦点时重置搜索状态
  useEffect(() => {
    if (!isFocused) {
      setIsSearchMode(false);
      setSearchText('');
      setSearchResults([]);
      setActiveSearchTab('chat');
      setActionMenuVisible(false);
      Keyboard.dismiss();
    }
  }, [isFocused]);

  // 处理 Android 物理返回键 - 当显示通知页面时，返回键关闭通知页面
  useEffect(() => {
    const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
      if (showNotifications) {
        setShowNotifications(false);
        return true; // 阻止默认行为
      }
      return false;
    });

    return () => backHandler.remove();
  }, [showNotifications]);

  // 下拉刷新
  const onRefresh = useCallback(async () => {
    setRefreshing(true);
    await refresh();
    setRefreshing(false);
  }, [refresh]);

  // 格式化时间（稳定引用，配合会话行 memo）
  const formatTime = useCallback((dateString: string): string => {
    return formatTimeUtil(dateString);
  }, []);

  // 跳转到聊天页
  const handleConversationPress = (conversation: ConversationResponse, index: number) => {
    Animated.sequence([
      Animated.timing(scaleAnims[index], {
        toValue: 0.98,
        duration: 100,
        useNativeDriver: Platform.OS !== 'web',
      }),
      Animated.timing(scaleAnims[index], {
        toValue: 1,
        duration: 100,
        useNativeDriver: Platform.OS !== 'web',
      }),
    ]).start(() => {
      if (conversation.id === SYSTEM_MESSAGE_CHANNEL_ID) {
        // 系统通知 - 根据屏幕宽度决定如何显示
        if (isWideScreen) {
          // 宽屏下使用内部状态显示通知页面，同时设置系统消息为选中状态
          setSelectedConversation(systemMessageConversation);
          setShowNotifications(true);
        } else {
          // 窄屏下也使用内部状态显示通知页面
          setShowNotifications(true);
        }
      } else if (isWideScreen) {
        // 【桌面端双栏布局】宽屏下设置选中会话，在右侧显示聊天
        // 同时关闭系统通知页面
        setShowNotifications(false);
        setSelectedConversation(conversation);
      } else if (conversation.type === 'group' && conversation.group) {
        // 群聊 - 窄屏下导航
        router.push(
          hrefs.hrefChat({
            conversationId: String(conversation.id),
            groupId: String(conversation.group.id),
            groupName: conversation.group.name,
            groupAvatar: conversation.group.avatar,
            isGroupChat: true,
          })
        );
      } else {
        // 私聊 - 窄屏下导航
        const currentUserId = useAuthStore.getState().currentUser?.id;
        const otherUser = conversation.participants?.find(p => String(p.id) !== String(currentUserId));
        router.push(
          hrefs.hrefChat({
            conversationId: String(conversation.id),
            userId: otherUser ? String(otherUser.id) : undefined,
            isGroupChat: false,
          })
        );
      }
    });
  };

  const handleConversationPressRef = useRef(handleConversationPress);
  handleConversationPressRef.current = handleConversationPress;

  // 创建群聊
  const handleCreateGroup = () => {
    router.push(hrefs.hrefGroupCreate());
  };

  // 主动加群
  const handleJoinGroup = () => {
    router.push(hrefs.hrefGroupJoin());
  };

  const handleOpenActionMenu = () => {
    setActionMenuVisible(true);
  };

  const runMenuAction = (action: 'join' | 'create' | 'readAll' | 'scanQRCode') => {
    setActionMenuVisible(false);
    if (action === 'join') {
      handleJoinGroup();
      return;
    }
    if (action === 'create') {
      handleCreateGroup();
      return;
    }
    if (action === 'scanQRCode') {
      setScannerVisible(true);
      return;
    }
    handleMarkAllRead();
  };

  // 标记所有消息为已读
  const handleMarkAllRead = async () => {
    try {
      await markAllAsRead();
      setMessageUnreadCount(0);
    } catch (error) {
      console.error('标记已读失败:', error);
    }
  };

  // 进入搜索模式
  const handleSearch = () => {
    setIsSearchMode(true);
    setSearchText('');
    setSearchResults([]);
  };

  // 退出搜索模式
  const handleCloseSearch = () => {
    setIsSearchMode(false);
    setSearchText('');
    setSearchResults([]);
    Keyboard.dismiss();
  };

  // 执行搜索
  const performSearch = useCallback(async (keyword: string) => {
    if (!keyword.trim()) {
      setSearchResults([]);
      return;
    }

    const trimmedKeyword = keyword.trim().toLowerCase();
    setIsSearching(true);

    try {
      if (activeSearchTab === 'chat') {
        const results: SearchResultItem[] = [];

        for (const conv of conversationList) {
          await messageManager.fetchMessages(String(conv.id));
          const messages = messageManager.getMessages(String(conv.id));
          const matchedMessages = messages.filter(msg => {
            const text = extractTextFromSegments(msg.segments);
            return text.toLowerCase().includes(trimmedKeyword);
          });

          if (matchedMessages.length > 0) {
            results.push({
              type: 'conversation',
              conversation: conv,
              matchedMessages: matchedMessages,
            });
          }
        }

        setSearchResults(results);
      } else {
        const usersData = await authService.searchUsers(trimmedKeyword, 1, 20);
        const results: SearchResultItem[] = (usersData.list || []).map(user => ({
          type: 'user',
          user,
        }));
        setSearchResults(results);
      }
    } catch (error) {
      console.error('搜索失败:', error);
    } finally {
      setIsSearching(false);
    }
  }, [conversationList, activeSearchTab]);

  // 搜索文本变化时触发搜索
  useEffect(() => {
    const timer = setTimeout(() => {
      if (searchText.trim()) {
        performSearch(searchText);
      } else {
        setSearchResults([]);
      }
    }, 300);

    return () => clearTimeout(timer);
  }, [searchText, performSearch]);

  // 切换搜索Tab时重新搜索
  useEffect(() => {
    if (searchText.trim()) {
      performSearch(searchText);
    }
  }, [activeSearchTab, searchText, performSearch]);

  // 创建系统通知会话项
  const createSystemMessageItem = (): ConversationResponse => {
    const noticeContent = systemUnreadCount > 0 ? `您有 ${systemUnreadCount} 条未读通知` : '暂无新通知';
    return {
      id: SYSTEM_MESSAGE_CHANNEL_ID,
      type: 'private',
      last_seq: 0,
      last_message: {
        id: '0',
        conversation_id: SYSTEM_MESSAGE_CHANNEL_ID,
        sender_id: 'system',
        seq: 0,
        segments: [{ type: 'text', data: { text: noticeContent } }],
        status: 'normal',
        created_at: systemMessageTime,
      },
      last_message_at: systemMessageTime,
      unread_count: systemUnreadCount,
      participants: [],
      created_at: systemMessageTime,
      updated_at: systemMessageTime,
    };
  };

  // 合并列表数据：系统消息与普通会话一起按时间排序
  const listData: ConversationResponse[] = [
    createSystemMessageItem(),
    ...conversationList,
  ].sort((a, b) => {
    const aPinned = a.is_pinned ? 1 : 0;
    const bPinned = b.is_pinned ? 1 : 0;
    if (aPinned !== bPinned) return bPinned - aPinned;
    const aTime = new Date(a.updated_at || 0).getTime();
    const bTime = new Date(b.updated_at || 0).getTime();
    if (Number.isNaN(aTime) || Number.isNaN(bTime)) return 0;
    return bTime - aTime;
  });

  const listConvRef = useRef(new Map<string, ConversationResponse>());
  listConvRef.current = new Map(listData.map((c) => [String(c.id), c]));

  const stableConversationPress = useCallback((conversationId: string, index: number) => {
    const c = listConvRef.current.get(conversationId);
    if (c) {
      handleConversationPressRef.current(c, index);
    }
  }, []);

  // 总未读数
  const totalUnread = totalUnreadCount + systemUnreadCount;

  // 渲染会话项（行级 memo + 按 id 解析最新会话，避免 Tab 切换时整表无效重绘）
  const renderConversation = useCallback<ListRenderItem<ConversationResponse>>(
    ({ item, index }) => {
      const isSelected = selectedConversation?.id === item.id;
      return (
        <ConversationListRow
          item={item}
          index={index}
          scale={scaleAnims[index] ?? 1}
          isSelected={isSelected}
          formatTime={formatTime}
          systemChannelId={SYSTEM_MESSAGE_CHANNEL_ID}
          onPress={() => stableConversationPress(String(item.id), index)}
        />
      );
    },
    [selectedConversation?.id, scaleAnims, formatTime, stableConversationPress]
  );

  // 渲染空状态
  const renderEmpty = () => (
    <EmptyState
      title="暂无消息"
      description="开始聊天吧，与其他用户交流互动"
      icon="message-text-outline"
    />
  );

  // 高亮搜索关键词
  const highlightKeyword = (text: string, keyword: string): React.ReactNode => {
    if (!text || !keyword) return text;
    
    const lowerText = text.toLowerCase();
    const lowerKeyword = keyword.toLowerCase();
    const index = lowerText.indexOf(lowerKeyword);
    
    if (index === -1) return text;
    
    return (
      <Text>
        <Text>{text.substring(0, index)}</Text>
        <Text style={styles.highlightText}>{text.substring(index, index + keyword.length)}</Text>
        <Text>{text.substring(index + keyword.length)}</Text>
      </Text>
    );
  };

  // 渲染搜索结果项
  const renderSearchResult = ({ item }: { item: SearchResultItem }) => {
    if (item.type === 'conversation' && item.conversation) {
      const conv = item.conversation;
      const otherUser = conv.participants?.find(
        p => String(p.id) !== String(currentUserId)
      );
      const matchedMessages = item.matchedMessages || [];
      
      return (
        <TouchableOpacity
          style={styles.searchResultItem}
          onPress={() => handleConversationPress(conv, 0)}
        >
          <Avatar
            source={otherUser?.avatar || null}
            size={44}
            name={otherUser?.nickname || '未知用户'}
          />
          <View style={styles.searchResultContent}>
            <View style={styles.searchResultHeader}>
              <Text style={styles.searchResultName}>
                {otherUser?.nickname || otherUser?.username || '未知用户'}
              </Text>
              {matchedMessages.length > 0 && (
                <Text style={styles.searchResultTime}>
                  {matchedMessages.length} 条相关消息
                </Text>
              )}
            </View>
            <View style={styles.matchedMessagesContainer}>
              {matchedMessages.map((msg, idx) => (
                <View key={msg.id || idx} style={styles.matchedMessageItem}>
                  <Text style={styles.matchedMessageText} numberOfLines={2}>
                    {highlightKeyword(extractTextFromSegments(msg.segments), searchText)}
                  </Text>
                  <Text style={styles.matchedMessageTime}>
                    {formatTime(msg.created_at)}
                  </Text>
                </View>
              ))}
            </View>
          </View>
          <MaterialCommunityIcons name="chevron-right" size={20} color={colors.chat.iconSoft} />
        </TouchableOpacity>
      );
    }
    
    if (item.type === 'user' && item.user) {
      const user = item.user;
      
      return (
        <TouchableOpacity
          style={styles.searchResultItem}
          onPress={async () => {
            try {
              const conversation = await createConversation(String(user.id));
              
              if (conversation) {
                router.push(
                  hrefs.hrefChat({
                    conversationId: String(conversation.id),
                    userId: String(user.id),
                    isGroupChat: false,
                  })
                );
              }
            } catch (error) {
              console.error('创建会话失败:', error);
            }
          }}
        >
          <Avatar
            source={user.avatar}
            size={44}
            name={user.nickname}
          />
          <View style={styles.searchResultContent}>
            <Text style={styles.searchResultName}>
              {highlightKeyword(user.nickname, searchText)}
            </Text>
            <Text style={styles.searchResultMessage} numberOfLines={1}>
              {highlightKeyword(`@${user.username}`, searchText)}
              {user.bio ? ` · ${highlightKeyword(user.bio, searchText)}` : ''}
            </Text>
          </View>
          {user.is_following && (
            <View style={styles.followingBadge}>
              <MaterialCommunityIcons name="check" size={14} color={colors.primary.main} />
            </View>
          )}
          {!user.is_following && (
            <MaterialCommunityIcons name="chevron-right" size={20} color={colors.chat.iconSoft} />
          )}
        </TouchableOpacity>
      );
    }
    
    return null;
  };

  // 渲染搜索空状态
  const renderSearchEmpty = () => {
    if (isSearching) {
      return (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="small" color={colors.primary.main} />
          <Text style={styles.searchingText}>搜索中...</Text>
        </View>
      );
    }
    
    if (searchText.trim() && searchResults.length === 0) {
      return (
        <EmptyState
          title={`未找到相关${activeSearchTab === 'chat' ? '聊天记录' : '用户'}`}
          description="试试其他关键词吧"
          icon={activeSearchTab === 'chat' ? 'message-search-outline' : 'account-search-outline'}
        />
      );
    }
    
    if (!searchText.trim()) {
      return (
        <EmptyState
          title="搜索聊天记录或用户"
          description="输入关键词开始搜索"
          icon="magnify"
        />
      );
    }
    
    return null;
  };

  // 渲染搜索模式UI（扁平化现代化设计）
  const renderSearchMode = () => (
    <View style={styles.searchModeContainer}>
      {/* 搜索顶栏（统一组件，内置硬件返回键拦截） */}
      <SearchHeader
        value={searchText}
        onChangeText={setSearchText}
        onSubmit={() => performSearch(searchText)}
        onCancel={handleCloseSearch}
        placeholder={activeSearchTab === 'chat' ? '搜索聊天记录' : '搜索用户'}
        compact
      />

      {/* Tab切换 - 与主页一致的下划线风格 */}
      <View style={styles.searchTabContainer}>
        <TabBar
          tabs={['聊天记录', '用户']}
          activeIndex={activeSearchTab === 'chat' ? 0 : 1}
          onTabChange={(index) => setActiveSearchTab(index === 0 ? 'chat' : 'user')}
          variant="home"
          style={{
            paddingHorizontal: spacing.md,
            paddingVertical: spacing.xs,
          }}
        />
      </View>

      {/* 搜索结果 */}
      <FlashList
        data={searchResults}
        renderItem={renderSearchResult}
        keyExtractor={(item, index) => {
          if (item.type === 'conversation') {
            return `conv-${item.conversation?.id || index}`;
          }
          return `user-${item.user?.id || index}`;
        }}
        contentContainerStyle={{
          paddingHorizontal: spacing.md,
          paddingTop: spacing.sm,
          paddingBottom: listBottomInset,
        }}
        showsVerticalScrollIndicator={false}
        scrollEnabled={true}
        keyboardShouldPersistTaps="handled"
        keyboardDismissMode="on-drag"
        drawDistance={250}
        ListEmptyComponent={renderSearchEmpty}
      />
    </View>
  );

  // 渲染会话列表内容
  const renderConversationList = () => (
    <>
      <View style={[styles.header, ...(isWideScreen ? [styles.headerWide] : [])]}>
        <View style={styles.headerLeft} />

        <View style={styles.headerCenter}>
          <Text style={[styles.headerTitle, ...(isWideScreen ? [styles.headerTitleWide] : [])]}>消息</Text>
          {totalUnread > 0 && (
            <View style={styles.totalBadge}>
              <Text style={styles.totalBadgeText}>{totalUnread > 99 ? '99+' : totalUnread}</Text>
            </View>
          )}
        </View>

        <View style={styles.headerRightContainer}>
          <TouchableOpacity style={styles.headerRightBtn} onPress={handleOpenActionMenu}>
            <MaterialCommunityIcons name="plus" size={24} color={colors.text.secondary} />
          </TouchableOpacity>
        </View>
      </View>

      <TouchableOpacity
        style={[styles.searchContainer, ...(isWideScreen ? [styles.searchContainerWide] : [])]}
        onPress={handleSearch}
        activeOpacity={0.85}
      >
        <View pointerEvents="none">
          <SearchBar
            value=""
            onChangeText={() => {}}
            onSubmit={() => {}}
            placeholder="搜索"
          />
        </View>
      </TouchableOpacity>

      {isLoading && conversationList.length === 0 ? (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color={colors.primary.main} />
        </View>
      ) : (
        <FlashList
          data={listData}
          renderItem={renderConversation}
          keyExtractor={(item) => String(item.id)}
          contentContainerStyle={{
            backgroundColor: colors.background.default,
            paddingHorizontal: spacing.xs,
            paddingBottom: listBottomInset,
          }}
          showsVerticalScrollIndicator={false}
          ListEmptyComponent={renderEmpty}
          onEndReached={onEndReached}
          onEndReachedThreshold={0.5}
          scrollEnabled={true}
          keyboardShouldPersistTaps="handled"
          keyboardDismissMode="on-drag"
          drawDistance={250}
          refreshControl={
            <RefreshControl
              refreshing={refreshing}
              onRefresh={onRefresh}
              colors={[colors.primary.main]}
              tintColor={colors.primary.main}
            />
          }
          ListFooterComponent={
            loadingMore ? (
              <View style={styles.loadingMoreContainer}>
                <ActivityIndicator size="small" color={colors.primary.main} />
                <Text style={styles.loadingMoreText}>加载中...</Text>
              </View>
            ) : null
          }
        />
      )}
    </>
  );

  const renderActionMenu = () => (
    <Modal visible={actionMenuVisible} transparent animationType="fade" onRequestClose={() => setActionMenuVisible(false)}>
      <Pressable style={styles.actionMenuBackdrop} onPress={() => setActionMenuVisible(false)}>
        <View style={styles.actionMenu}>
          <TouchableOpacity style={styles.actionMenuItem} onPress={() => runMenuAction('scanQRCode')}>
            <MaterialCommunityIcons name="qrcode-scan" size={21} color={colors.text.primary} />
            <Text style={styles.actionMenuText}>扫码登录</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.actionMenuItem} onPress={() => runMenuAction('join')}>
            <MaterialCommunityIcons name="account-plus-outline" size={21} color={colors.text.primary} />
            <Text style={styles.actionMenuText}>加入群聊</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.actionMenuItem} onPress={() => runMenuAction('create')}>
            <MaterialCommunityIcons name="account-multiple-plus" size={21} color={colors.text.primary} />
            <Text style={styles.actionMenuText}>创建群聊</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.actionMenuItem} onPress={() => runMenuAction('readAll')} disabled={isMarking}>
            <MaterialCommunityIcons name="message-check-outline" size={21} color={colors.text.primary} />
            <Text style={styles.actionMenuText}>{isMarking ? '处理中...' : '全部已读'}</Text>
          </TouchableOpacity>
        </View>
      </Pressable>
    </Modal>
  );

  // 桌面端双栏布局
  if (isWideScreen && !isSearchMode) {
    return (
      <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
        <View style={styles.desktopContainer}>
          {/* 左侧会话列表 */}
          <View style={[styles.sidebar, { width: sidebarWidth }]}>
            {renderConversationList()}
          </View>
          
          {/* 右侧内容区域 - 使用 flex:1 填充剩余空间 */}
          <View style={styles.chatArea}>
            {showNotifications ? (
              // 显示系统通知页面
              (<NotificationsScreen onBack={stableCloseNotifications} />)
            ) : selectedConversation ? (
              // 显示选中会话的聊天内容
              (<ChatScreen
                isEmbedded
                embeddedConversationId={String(selectedConversation.id)}
                embeddedIsGroupChat={selectedConversation.type === 'group'}
                embeddedGroupId={selectedConversation.group ? String(selectedConversation.group.id) : undefined}
                embeddedGroupName={selectedConversation.group?.name}
                onEmbeddedBack={stableClearSelectedConversation}
              />)
            ) : (
              // 默认占位符
              (<View style={styles.chatPlaceholder}>
                <View style={styles.chatPlaceholderContent}>
                  <MaterialCommunityIcons name="message-text-outline" size={64} color={colors.chat.iconMuted} />
                  <Text style={styles.chatPlaceholderText}>选择一个会话开始聊天</Text>
                </View>
              </View>)
            )}
          </View>
        </View>
        {renderActionMenu()}
      </SafeAreaView>
    );
  }

  return (
    <SafeAreaView style={styles.container} edges={['top', 'bottom']}>
      {showNotifications ? (
        // 显示系统通知页面，传入 onBack 回调
        (<NotificationsScreen onBack={stableCloseNotifications} />)
      ) : isSearchMode ? (
        renderSearchMode()
      ) : isWideScreen ? (
        <ResponsiveContainer maxWidth={800}>
          {renderConversationList()}
        </ResponsiveContainer>
      ) : (
        renderConversationList()
      )}
      {renderActionMenu()}
      <QRCodeScanner visible={scannerVisible} onClose={stableCloseScanner} />
    </SafeAreaView>
  );
};

function createMessageListStyles(colors: AppColors) {
  return StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: colors.background.default,
    },
    // 桌面端双栏布局
    desktopContainer: {
      flex: 1,
      flexDirection: 'row',
    },
    sidebar: {
      backgroundColor: colors.background.default,
      borderRightWidth: 1,
      borderRightColor: colors.chat.border,
    },
    chatArea: {
      flex: 1,
      backgroundColor: colors.chat.surfaceMuted,
    },
    chatPlaceholder: {
      flex: 1,
      backgroundColor: colors.chat.surfaceMuted,
      alignItems: 'center',
      justifyContent: 'center',
    },
    chatPlaceholderContent: {
      alignItems: 'center',
      justifyContent: 'center',
    },
    chatPlaceholderText: {
      marginTop: spacing.md,
      fontSize: 16,
      color: colors.text.hint,
    },
    header: {
      flexDirection: 'row',
      alignItems: 'center',
      justifyContent: 'space-between',
      paddingHorizontal: spacing.md,
      paddingVertical: spacing.md,
      backgroundColor: colors.background.default,
      borderBottomWidth: StyleSheet.hairlineWidth,
      borderBottomColor: colors.divider + '60',
    },
    headerWide: {
      paddingHorizontal: spacing.lg,
      paddingVertical: spacing.lg,
    },
    headerTitleWide: {
      fontSize: 22,
    },
    searchContainerWide: {
      paddingHorizontal: spacing.lg,
    },
    listContentWide: {
      paddingHorizontal: spacing.xs,
    },
    headerLeft: {
      width: 44,
    },
    headerCenter: {
      flexDirection: 'row',
      alignItems: 'center',
      gap: spacing.xs,
    },
    headerTitle: {
      fontSize: 19,
      fontWeight: '700',
      color: colors.text.primary,
    },
    totalBadge: {
      minWidth: 18,
      height: 18,
      borderRadius: 9,
      backgroundColor: colors.error.main,
      alignItems: 'center',
      justifyContent: 'center',
      paddingHorizontal: 5,
    },
    totalBadgeText: {
      color: colors.primary.contrast,
      fontSize: 11,
      fontWeight: '600',
      lineHeight: 18,
      textAlignVertical: 'center',
      includeFontPadding: false,
    },
    headerRight: {
      width: 44,
      height: 44,
      alignItems: 'center',
      justifyContent: 'center',
    },
    headerRightContainer: {
      flexDirection: 'row',
      alignItems: 'center',
    },
    headerRightBtn: {
      width: 36,
      height: 44,
      alignItems: 'center',
      justifyContent: 'center',
    },
    actionMenuBackdrop: {
      flex: 1,
      backgroundColor: 'rgba(0,0,0,0.08)',
    },
    actionMenu: {
      position: 'absolute',
      top: 88,
      right: spacing.md,
      width: 188,
      backgroundColor: colors.background.paper,
      borderRadius: 12,
      paddingVertical: spacing.sm,
      ...shadows.md,
    },
    actionMenuItem: {
      flexDirection: 'row',
      alignItems: 'center',
      paddingHorizontal: spacing.md,
      paddingVertical: spacing.md,
    },
    actionMenuText: {
      marginLeft: spacing.sm,
      fontSize: 16,
      color: colors.text.primary,
    },
    searchContainer: {
      paddingHorizontal: spacing.md,
      paddingBottom: spacing.sm,
      backgroundColor: colors.background.default,
    },

    listContent: {
      flexGrow: 1,
      backgroundColor: colors.background.default,
      paddingHorizontal: spacing.xs,
    },
    loadingContainer: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      paddingVertical: spacing.xl * 2,
    },
    loadingMoreContainer: {
      flexDirection: 'row',
      alignItems: 'center',
      justifyContent: 'center',
      paddingVertical: spacing.md,
    },
    loadingMoreText: {
      marginLeft: spacing.sm,
      fontSize: 14,
      color: colors.text.hint,
    },
    searchModeContainer: {
      flex: 1,
      backgroundColor: colors.background.default,
    },
    searchTabContainer: {
      backgroundColor: colors.background.default,
      borderBottomWidth: 1,
      borderBottomColor: `${colors.divider}50`,
    },
    searchResultsContent: {
      flexGrow: 1,
      paddingHorizontal: spacing.md,
      paddingTop: spacing.sm,
    },
    searchResultItem: {
      flexDirection: 'row',
      alignItems: 'center',
      padding: spacing.md,
      backgroundColor: colors.background.default,
      borderBottomWidth: StyleSheet.hairlineWidth,
      borderBottomColor: `${colors.divider}50`,
    },
    searchResultContent: {
      flex: 1,
      marginLeft: spacing.md,
    },
    searchResultHeader: {
      flexDirection: 'row',
      justifyContent: 'space-between',
      alignItems: 'center',
      marginBottom: 2,
    },
    searchResultName: {
      fontSize: 15,
      fontWeight: '600',
      color: colors.text.primary,
    },
    searchResultTime: {
      fontSize: 12,
      color: colors.text.hint,
    },
    searchResultMessage: {
      fontSize: 13,
      color: colors.text.secondary,
    },
    searchingText: {
      marginTop: spacing.sm,
      fontSize: 14,
      color: colors.text.hint,
    },
    followingBadge: {
      width: 24,
      height: 24,
      borderRadius: 12,
      backgroundColor: colors.primary.light + '30',
      alignItems: 'center',
      justifyContent: 'center',
    },
    highlightText: {
      color: colors.primary.main,
      fontWeight: '700',
      backgroundColor: colors.primary.light + '30',
    },
    matchedMessagesContainer: {
      marginTop: spacing.sm,
    },
    matchedMessageItem: {
      flexDirection: 'row',
      justifyContent: 'space-between',
      alignItems: 'flex-start',
      paddingVertical: spacing.xs,
      borderBottomWidth: StyleSheet.hairlineWidth,
      borderBottomColor: colors.divider,
    },
    matchedMessageText: {
      flex: 1,
      fontSize: 13,
      color: colors.text.secondary,
      lineHeight: 18,
    },
    matchedMessageTime: {
      fontSize: 11,
      color: colors.text.hint,
      marginLeft: spacing.sm,
      minWidth: 45,
    },
  });
}
