/**
 * ChatScreen 自定义 Hook
 * 管理聊天的所有状态和逻辑
 *
 * 【重构后】完全依赖 MessageManager 架构
 * - 消息数据通过 MessageManager 管理
 * - 会话详情通过 useChat 返回的 conversation 获取
 * - 发送者信息通过 MessageManager 维护
 * - 输入状态、禁言状态通过 MessageManager 管理
 * - 解决竞态条件和状态同步问题
 */

import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import {
  Keyboard,
  Platform,
  KeyboardEvent,
  Alert,
} from 'react-native';
import { useLocalSearchParams, router } from 'expo-router';
import { formatDistanceToNow } from 'date-fns';
import { zhCN } from 'date-fns/locale';
import * as ImagePicker from 'expo-image-picker';
import { GroupMemberResponse, MessageSegment, TextSegmentData, ImageSegmentData, AtSegmentData, ReplySegmentData, MessageStatus } from '../../../../types/dto';
import { messageService } from '../../../../services/messageService';
import { uploadService } from '../../../../services/uploadService';
import { ApiError } from '../../../../services/api';
// 【新架构】使用 MessageManager
import { useChat, useGroupTyping, useGroupMuted, messageManager } from '../../../../stores';
import { groupService } from '../../../../services/groupService';
import { userManager } from '../../../../stores/userManager';
import { groupManager } from '../../../../stores/groupManager';
import * as hrefs from '../../../../navigation/hrefs';
import { firstRouteParam } from '../../../../navigation/paramUtils';
import {
  GroupMessage,
  PanelType,
  UserRole,
  SenderInfo,
  ChatRouteParams,
  MenuPosition,
  PendingChatAttachment,
} from './types';
import { TIME_SEPARATOR_INTERVAL, MEMBERS_PAGE_SIZE, MAX_PENDING_CHAT_IMAGES } from './constants';
import {
  deleteMessage as deleteMessageFromDb,
  clearConversationMessages,
} from '../../../../services/database';

export const useChatScreen = () => {
  const getSendErrorMessage = useCallback((error: unknown, fallback: string) => {
    if (error instanceof ApiError && error.message) {
      return error.message;
    }
    return fallback;
  }, []);

  const rawParams = useLocalSearchParams<{
    conversationId?: string | string[];
    userId?: string | string[];
    isGroupChat?: string | string[];
    groupId?: string | string[];
    groupName?: string | string[];
  }>();
  // 路由参数（动态段 + query）；群 ID 勿用 Number()，避免超过 2^53-1 时精度丢失
  const routeParams = useMemo(() => {
    const isGroupFlag = firstRouteParam(rawParams.isGroupChat);
    return {
      conversationId: firstRouteParam(rawParams.conversationId) ?? null,
      userId: firstRouteParam(rawParams.userId) ?? null,
      isGroupChat: isGroupFlag === '1' || isGroupFlag === 'true',
      groupId: firstRouteParam(rawParams.groupId),
      groupName: firstRouteParam(rawParams.groupName),
    };
  }, [
    rawParams.conversationId,
    rawParams.userId,
    rawParams.isGroupChat,
    rawParams.groupId,
    rawParams.groupName,
  ]);

  const { conversationId: routeConversationId, userId: routeUserId, isGroupChat, groupId: routeGroupId, groupName: routeGroupName } = routeParams;

  // 当前会话ID（可能在新建私聊会话后动态更新）
  const [conversationId, setConversationId] = useState<string | null>(routeConversationId);

  // 【新架构】使用 MessageManager 的 hook 获取所有数据
  const {
    messages: messageManagerMessages,
    isLoadingMessages,
    hasMoreMessages,
    loadMoreMessages,
    refreshMessages,
    sendMessage: sendMessageViaManager,
    isSending: isSendingViaManager,
    markAsRead,
    conversation,
  } = useChat(conversationId);

  // 本地状态
  const [currentUserId, setCurrentUserId] = useState<string>('');

  // 【新架构】使用 MessageManager 获取群聊输入状态和禁言状态
  const { typingUsers: groupTypingUsers } = useGroupTyping(routeGroupId ? String(routeGroupId) : null);
  const { isMuted: isMutedFromManager, setMuted: setMutedStatus } = useGroupMuted(
    routeGroupId ? String(routeGroupId) : null,
    currentUserId
  );

  // 本地状态
  const [inputText, setInputText] = useState('');
  const [otherUser, setOtherUser] = useState<{ id?: string; nickname?: string; avatar?: string | null } | null>(null);
  const [isFollowedByOther, setIsFollowedByOther] = useState<boolean | null>(null);
  const [currentUser, setCurrentUser] = useState<{ id?: string; nickname?: string; avatar?: string | null } | null>(null);
  const [keyboardHeight, setKeyboardHeight] = useState(0);
  const [loading, setLoading] = useState(true);
  const [sending, setSending] = useState(false);
  const [lastSeq, setLastSeq] = useState<number>(0);
  const [firstSeq, setFirstSeq] = useState<number>(0);
  const [otherUserLastReadSeq, setOtherUserLastReadSeq] = useState<number>(0);
  const [activePanel, setActivePanel] = useState<PanelType>('none');
  const [sendingImage, setSendingImage] = useState(false);
  const [uploadingAttachments, setUploadingAttachments] = useState(false);
  const [pendingAttachments, setPendingAttachments] = useState<PendingChatAttachment[]>([]);
  const [loadingMore, setLoadingMore] = useState(false);
  const [hasMoreHistory, setHasMoreHistory] = useState(true);
  const flatListRef = useRef<any>(null);
  const textInputRef = useRef<any>(null);

  // 滚动状态机 refs（Telegram/Element 风格：底部粘附 + 阅读锚点）
  const scrollPositionRef = useRef({ contentHeight: 0, scrollY: 0, viewportHeight: 0 });
  const hasInitialAnchorDoneRef = useRef(false);
  const prevMessageCountRef = useRef(0);
  const prevLatestSeqRef = useRef(0);
  const prevMarkedReadSeqRef = useRef(0);
  const enterMarkedKeyRef = useRef<string>('');
  const isProgrammaticScrollRef = useRef(false);
  const suppressAutoFollowRef = useRef(false);
  const isBrowsingHistoryRef = useRef(false);
  const hasShownMessageListRef = useRef(false);
  const historyLoadingLockUntilRef = useRef(0);

  // 回复消息状态
  const [replyingTo, setReplyingTo] = useState<GroupMessage | null>(null);

  // 长按菜单状态
  const [longPressMenuVisible, setLongPressMenuVisible] = useState(false);
  const [selectedMessage, setSelectedMessage] = useState<GroupMessage | null>(null);
  const [menuPosition, setMenuPosition] = useState<MenuPosition | undefined>(undefined);
  const [selectedMessageId, setSelectedMessageId] = useState<string | null>(null);

  // 群聊相关状态
  const [groupInfo, setGroupInfo] = useState<{ name?: string; member_count?: number } | null>(null);
  const [groupMembers, setGroupMembers] = useState<GroupMemberResponse[]>([]);
  const [currentUserRole, setCurrentUserRole] = useState<UserRole>('member');
  const [mentionQuery, setMentionQuery] = useState<string>('');
  const [selectedMentions, setSelectedMentions] = useState<string[]>([]);
  const [mentionAll, setMentionAll] = useState(false);

  const [isMuted, setIsMuted] = useState(false);
  const [muteAll, setMuteAll] = useState(false);

  // 路由会话ID变化时同步到本地会话状态，确保订阅会随会话切换
  useEffect(() => {
    setConversationId(routeConversationId);
  }, [routeConversationId]);

  // 【改造】直接使用 MessageManager 返回的消息
  const messages = useMemo<GroupMessage[]>(() => {
    return messageManagerMessages.map(m => ({
      id: m.id,
      conversation_id: m.conversation_id,
      sender_id: m.sender_id,
      seq: m.seq,
      segments: m.segments || [],
      status: (m.status || 'normal') as MessageStatus,
      category: m.category,
      created_at: m.created_at,
      sender: (m as any).sender,
      is_system_notice: (m as any).is_system_notice,
      notice_content: (m as any).notice_content,
    }));
  }, [messageManagerMessages]);

  // 对方用户ID（稳定来源）：优先路由参数，其次会话参与者，最后本地 otherUser
  const otherUserId = useMemo(() => {
    if (isGroupChat) return null;
    if (routeUserId) return String(routeUserId);
    const participants = conversation?.participants || [];
    if (participants.length > 0) {
      if (currentUserId) {
        const target = participants.find((p: any) => String(p.id) !== String(currentUserId));
        if (target?.id) return String(target.id);
      }
      if (participants.length === 1 && participants[0]?.id) return String(participants[0].id);
    }
    return otherUser?.id ? String(otherUser.id) : null;
  }, [isGroupChat, routeUserId, conversation?.participants, currentUserId, otherUser?.id]);

  // 私聊陌生人限制：未被对方关注时仅可发送1条文本消息，且禁止图片
  const followRestricted = useMemo(() => {
    if (isGroupChat) return false;
    // 仅使用独立关系状态源，避免 participants 覆盖造成误判
    return isFollowedByOther === false;
  }, [isGroupChat, isFollowedByOther]);
  const myPrivateSentCount = useMemo(() => {
    if (!followRestricted || !currentUserId) return 0;
    return messages.filter(m => String(m.sender_id) === String(currentUserId)).length;
  }, [messages, followRestricted, currentUserId]);
  const canSendFirstPrivateText = !followRestricted || myPrivateSentCount < 1;
  const canSendPrivateImage = !followRestricted;
  const followRestrictionHint = useMemo(() => {
    if (!followRestricted) return null;
    if (myPrivateSentCount >= 1) {
      return '对方未关注你前：仅可发送1条文字消息（已达上限）';
    }
    return '对方未关注你前：仅可发送1条文字消息，且不能发送图片';
  }, [followRestricted, myPrivateSentCount]);

  // 加载态语义修正：
  // isLoadingMessages 在分页加载历史时也会短暂为 true。
  // 若直接驱动 ChatScreen 的 loading，会导致消息列表被卸载重挂载，触发“回到底部”。
  // 这里只在“首屏且尚未展示过消息列表”时展示 loading 占位。
  useEffect(() => {
    if (messageManagerMessages.length > 0) {
      hasShownMessageListRef.current = true;
    }
    const shouldShowInitialLoading =
      !hasShownMessageListRef.current &&
      isLoadingMessages &&
      messageManagerMessages.length === 0;
    setLoading(shouldShowInitialLoading);
  }, [isLoadingMessages, messageManagerMessages.length]);

  // 【改造】同步 hasMore 状态
  useEffect(() => {
    setHasMoreHistory(hasMoreMessages);
  }, [hasMoreMessages]);

  // 【改造】同步发送状态
  useEffect(() => {
    setSending(isSendingViaManager);
  }, [isSendingViaManager]);

  // 【改造】同步禁言状态
  useEffect(() => {
    setIsMuted(isMutedFromManager);
  }, [isMutedFromManager]);

  // 【改造】从 conversation 对象获取会话详情
  useEffect(() => {
    if (!conversation) return;

    // 私聊模式：从 conversation.participants 获取对方用户信息
    if (!isGroupChat && conversation.participants) {
      if (!currentUserId) return;
      const currentUserIdStr = String(currentUserId);
      const other = conversation.participants.find((p: any) => p.id !== currentUserIdStr);
      if (other) {
        setOtherUser(prev => ({ ...(prev || {}), ...other }));
      }
      // 获取对方最后阅读位置
      setOtherUserLastReadSeq((conversation as any).other_last_read_seq || 0);
    }
  }, [conversation, isGroupChat, currentUserId]);

  // 独立同步私聊对象互关状态，避免 participants 缓存字段不完整或被刷新覆盖
  useEffect(() => {
    if (isGroupChat) return;
    if (!otherUserId) return;

    let cancelled = false;
    const syncRelationState = async () => {
      try {
        const detail = await userManager.getUserById(String(otherUserId), true);
        if (!detail || cancelled) return;
        setOtherUser(prev => ({ ...(prev || {}), ...detail }));
        if (typeof (detail as any).is_following_me === 'boolean') {
          setIsFollowedByOther((detail as any).is_following_me);
        } else {
          setIsFollowedByOther(null);
        }
      } catch (error) {
        console.error('同步私聊对象互关状态失败:', error);
        if (!cancelled) {
          setIsFollowedByOther(null);
        }
      }
    };

    syncRelationState();
    return () => {
      cancelled = true;
    };
  }, [isGroupChat, otherUserId]);

  // 进入新会话时重置滚动状态
  useEffect(() => {
    hasInitialAnchorDoneRef.current = false;
    prevMessageCountRef.current = 0;
    prevLatestSeqRef.current = 0;
    prevMarkedReadSeqRef.current = 0;
    enterMarkedKeyRef.current = '';
    suppressAutoFollowRef.current = false;
    isBrowsingHistoryRef.current = false;
    hasShownMessageListRef.current = false;
    historyLoadingLockUntilRef.current = 0;
  }, [conversationId]);

  useEffect(() => {
    setPendingAttachments([]);
  }, [conversationId]);

  const removePendingAttachment = useCallback((id: string) => {
    setPendingAttachments(prev => prev.filter(p => p.id !== id));
  }, []);

  const isComposerBusy = useMemo(
    () => sending || sendingImage || uploadingAttachments,
    [sending, sendingImage, uploadingAttachments]
  );

  const isHistoryLoadingLocked = useCallback(() => {
    return Date.now() < historyLoadingLockUntilRef.current;
  }, []);

  const scrollToLatest = useCallback((animated: boolean, force: boolean = false, reason: string = 'unknown') => {
    if (!force && (suppressAutoFollowRef.current || isBrowsingHistoryRef.current || isHistoryLoadingLocked())) return;
    // inverted 列表下，最新消息端对应 offset=0
    isProgrammaticScrollRef.current = true;
    flatListRef.current?.scrollToOffset({
      offset: 0,
      animated,
    });
    setTimeout(() => {
      isProgrammaticScrollRef.current = false;
    }, animated ? 220 : 32);
  }, [flatListRef, isHistoryLoadingLocked]);

  const isNearBottom = useCallback(() => {
    const scrollY = scrollPositionRef.current.scrollY || 0;
    // inverted 列表下，越接近 0 越靠近最新消息端
    return scrollY <= 100;
  }, [scrollPositionRef]);

  // 首屏加载完成后仅锚定一次到最新消息端
  useEffect(() => {
    if (
      loading ||
      loadingMore ||
      messages.length === 0 ||
      hasInitialAnchorDoneRef.current ||
      scrollPositionRef.current.viewportHeight <= 0
    ) {
      return;
    }
    hasInitialAnchorDoneRef.current = true;
    const timer = setTimeout(() => {
      scrollToLatest(false, true, 'initial-anchor');
    }, 0);
    return () => clearTimeout(timer);
  }, [loading, loadingMore, messages.length, scrollToLatest]);

  // 新消息跟随策略（Telegram/QQ 风格）：
  // 仅当“最新端消息 seq 增长”且用户在底部附近时才跟随；
  // 历史加载只会增加旧消息，不会提升 latest seq，因此不会触发回底。
  useEffect(() => {
    const currentCount = messages.length;
    const latestSeq = currentCount > 0 ? Math.max(...messages.map(m => m.seq || 0)) : 0;
    const prevLatestSeq = prevLatestSeqRef.current;
    prevMessageCountRef.current = currentCount;
    prevLatestSeqRef.current = latestSeq;

    if (loading || loadingMore) return;
    if (latestSeq <= prevLatestSeq) return;
    if (suppressAutoFollowRef.current) return;
    if (!isNearBottom()) return;

    const timer = setTimeout(() => {
      scrollToLatest(false, false, 'new-message-follow');
    }, 0);
    return () => clearTimeout(timer);
  }, [messages, loading, loadingMore, isNearBottom, scrollToLatest]);

  // 获取当前用户信息
  useEffect(() => {
    const fetchCurrentUser = async () => {
      try {
        const currentUserData = await userManager.getCurrentUser();
        if (currentUserData) {
          setCurrentUserId(String(currentUserData.id));
          setCurrentUser(currentUserData);
        }
      } catch (error) {
        console.error('获取当前用户失败:', error);
      }
    };
    fetchCurrentUser();
  }, []);

  // 群聊模式：获取群组信息和成员列表
  useEffect(() => {
    if (!isGroupChat || !routeGroupId) return;

    const fetchGroupInfo = async () => {
      try {
        const group = await groupManager.getGroup(routeGroupId);
        setGroupInfo(group);

        const membersResponse = await groupManager.getMembers(routeGroupId, 1, MEMBERS_PAGE_SIZE);
        const members = membersResponse.list || [];
        setGroupMembers(members);

        const myMember = members.find((m: any) => m.user_id === currentUserId);
        if (myMember) {
          setCurrentUserRole(myMember.role);
        }

        try {
          const myInfo = await groupService.getMyMemberInfo(routeGroupId);
          setIsMuted(myInfo.is_muted);
          setMutedStatus(myInfo.is_muted);
          setMuteAll(myInfo.mute_all);
        } catch (error) {
          console.error('获取成员信息失败:', error);
        }
      } catch (error) {
        const isGroupNotFound =
          error instanceof ApiError &&
          (error.code === 404 ||
            error.message === '群组不存在' ||
            error.message.includes('群组不存在'));

        if (isGroupNotFound) {
          Alert.alert('提示', '该群组不存在或已解散', [
            {
              text: '确定',
              onPress: () => {
                if (router.canGoBack()) {
                  router.back();
                } else {
                  router.replace(hrefs.hrefMessages());
                }
              },
            },
          ]);
          return;
        }

        console.error('获取群组信息失败:', error);
        Alert.alert('错误', getSendErrorMessage(error, '无法获取群组信息'));
      }
    };

    if (currentUserId) {
      fetchGroupInfo();
    }
  }, [isGroupChat, routeGroupId, currentUserId, setMutedStatus]);

  // 私聊模式：创建或获取会话
  useEffect(() => {
    if (isGroupChat) return;

    let isCancelled = false;

    const createOrGetConversation = async () => {
      if (conversationId) return;
      if (!routeUserId) return;

      try {
        setLoading(true);
        const response = await messageService.createConversation(routeUserId);

        if (isCancelled) return;

        setConversationId(response.id);

        if (response.participants && response.participants.length > 0) {
          const other = response.participants.find((p: any) => p.id !== currentUserId);
          if (other) {
            setOtherUser(other);
          }
        }
      } catch (error) {
        console.error('创建会话失败:', error);
        Alert.alert('错误', '无法创建会话');
      } finally {
        if (!isCancelled) {
          setLoading(false);
        }
      }
    };

    createOrGetConversation();

    return () => {
      isCancelled = true;
    };
  }, [routeUserId, conversationId, currentUserId, isGroupChat]);

  // 加载更多历史消息（inverted 下保持阅读锚点）
  const loadMoreHistory = useCallback(async () => {
    if (!conversationId || !hasMoreHistory || loadingMore) {
      return;
    }

    // 历史加载期间禁止“新消息自动跟随到底”
    suppressAutoFollowRef.current = true;
    isBrowsingHistoryRef.current = true;
    historyLoadingLockUntilRef.current = Date.now() + 3000;

    // 保存加载前的滚动位置和内容高度
    const scrollYBefore = scrollPositionRef.current.scrollY;
    const contentHeightBefore = scrollPositionRef.current.contentHeight;
    setLoadingMore(true);

    try {
      await loadMoreMessages();

      // 更新 firstSeq
      if (messages.length > 0) {
        const minSeq = Math.min(...messages.map(m => m.seq));
        setFirstSeq(minSeq);
      }

      // inverted + maintainVisibleContentPosition 下由列表原生保持位置
      // 不做手动 scrollToOffset，避免与原生锚点冲突导致回到底部
    } catch (error) {
      console.error('加载历史消息失败:', error);
    } finally {
      setLoadingMore(false);
      // 加载结束后继续保留短暂锁窗，避免布局结算阶段误触自动回底
      historyLoadingLockUntilRef.current = Date.now() + 800;
    }
  }, [conversationId, hasMoreHistory, loadingMore, loadMoreMessages, messages]);

  // 列表内容尺寸变化：仅同步内容高度，锚点补偿由 loadMoreHistory 统一处理
  const handleMessageListContentSizeChange = useCallback((contentWidth: number, contentHeight: number) => {
    scrollPositionRef.current.contentHeight = contentHeight;
  }, []);

  const handleReachLatestEdge = useCallback(() => {
    if (isHistoryLoadingLocked()) return;
    suppressAutoFollowRef.current = false;
    isBrowsingHistoryRef.current = false;
  }, [isHistoryLoadingLocked]);

  /** 用户点击「回到底部」：解除浏览历史锁并滚到最新消息端（inverted 下 offset=0） */
  const jumpToLatestMessages = useCallback(() => {
    suppressAutoFollowRef.current = false;
    isBrowsingHistoryRef.current = false;
    scrollToLatest(true, true, 'jump-latest-button');
  }, [scrollToLatest]);

  const setBrowsingHistory = useCallback((browsing: boolean) => {
    isBrowsingHistoryRef.current = browsing;
  }, []);

  // 进入聊天详情后立即清未读（不依赖滚动位置）
  useEffect(() => {
    if (!conversationId) return;
    if (!conversation) return;

    const unreadCount = Number((conversation as any).unread_count || 0);
    if (unreadCount <= 0) return;

    const latestFromConversation = Number((conversation as any).last_seq || 0);
    const latestFromMessages = messages.length > 0 ? Math.max(...messages.map(m => m.seq || 0)) : 0;
    const targetSeq = Math.max(latestFromConversation, latestFromMessages);
    if (targetSeq <= 0) return;

    const markKey = `${conversationId}:${targetSeq}`;
    if (enterMarkedKeyRef.current === markKey) return;
    enterMarkedKeyRef.current = markKey;

    prevMarkedReadSeqRef.current = Math.max(prevMarkedReadSeqRef.current, targetSeq);
    markAsRead(targetSeq).catch(error => {
      console.error('[ChatScreen] 进入会话清未读失败:', error);
    });
  }, [conversationId, conversation, messages, markAsRead]);

  // 自动标记已读（QQ/Telegram 风格）：
  // 仅当出现更大的 latest seq，且用户在最新端附近时才上报。
  // 历史加载/浏览历史不会触发 read。
  useEffect(() => {
    if (!conversationId || messages.length === 0) return;
    if (loading || loadingMore) return;
    if (suppressAutoFollowRef.current || isBrowsingHistoryRef.current) return;
    if (!isNearBottom()) return;

    const latestSeq = Math.max(...messages.map(m => m.seq), 0);
    if (latestSeq <= 0) return;

    // 没有新增最新消息，不重复上报
    if (latestSeq <= prevLatestSeqRef.current) return;
    prevLatestSeqRef.current = latestSeq;

    // 避免对同一 seq 重复标记
    if (latestSeq <= prevMarkedReadSeqRef.current) return;
    prevMarkedReadSeqRef.current = latestSeq;

    markAsRead(latestSeq).catch(error => {
      console.error('[ChatScreen] 自动标记已读失败:', error);
    });
  }, [messages, conversationId, markAsRead, loading, loadingMore, isNearBottom]);

  // 使用 ref 存储 groupMembers
  const groupMembersRef = useRef(groupMembers);
  useEffect(() => {
    groupMembersRef.current = groupMembers;
  }, [groupMembers]);

  // 使用 ref 存储 currentUserId
  const currentUserIdRef = useRef(currentUserId);
  useEffect(() => {
    currentUserIdRef.current = currentUserId;
  }, [currentUserId]);

  // 监听键盘事件
  useEffect(() => {
    const keyboardWillShow = (e: KeyboardEvent) => {
      setKeyboardHeight(e.endCoordinates.height);
      setActivePanel(prev => prev === 'mention' ? 'mention' : 'none');
    };

    const keyboardWillHide = () => {
      setKeyboardHeight(0);
    };

    const showSubscription = Keyboard.addListener(
      Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow',
      keyboardWillShow
    );
    const hideSubscription = Keyboard.addListener(
      Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide',
      keyboardWillHide
    );

    return () => {
      showSubscription.remove();
      hideSubscription.remove();
    };
  }, []);

  // 格式化时间
  const formatTime = useCallback((dateString: string): string => {
    try {
      const date = new Date(dateString);
      const now = new Date();
      const diffInHours = (now.getTime() - date.getTime()) / (1000 * 60 * 60);

      if (diffInHours < 24 && date.getDate() === now.getDate()) {
        return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
      }

      return formatDistanceToNow(date, {
        addSuffix: true,
        locale: zhCN,
      });
    } catch {
      return '';
    }
  }, []);

  // 检查是否需要显示时间分隔
  const shouldShowTime = useCallback((index: number): boolean => {
    if (index === 0) return true;
    const currentMsg = messages[index];
    const prevMsg = messages[index - 1];
    const currentTime = new Date(currentMsg.created_at).getTime();
    const prevTime = new Date(prevMsg.created_at).getTime();
    return (currentTime - prevTime) > TIME_SEPARATOR_INTERVAL;
  }, [messages]);

  // 处理输入变化，检测@符号
  const handleInputChange = useCallback((text: string) => {
    setInputText(text);

    if (isGroupChat) {
      const lastAtIndex = text.lastIndexOf('@');
      if (lastAtIndex !== -1) {
        const textAfterAt = text.slice(lastAtIndex + 1);
        if (!textAfterAt.includes(' ')) {
          setMentionQuery(textAfterAt.toLowerCase());
          setActivePanel('mention');
        } else {
          setActivePanel('none');
        }
      } else {
        setActivePanel('none');
      }
    }
  }, [isGroupChat]);

  // 【改造】获取发送者信息（群聊）- 优先从消息的 sender 字段获取
  const getSenderInfo = useCallback((senderId: string): SenderInfo => {
    if (senderId === currentUserId) {
      return {
        nickname: currentUser?.nickname || '我',
        avatar: currentUser?.avatar || null,
        userId: currentUserId,
      };
    }

    // 优先从消息列表中查找 sender 信息
    const messageWithSender = messages.find(m => m.sender_id === senderId && m.sender);
    if (messageWithSender?.sender) {
      return {
        nickname: messageWithSender.sender.nickname || messageWithSender.sender.username || '用户',
        avatar: messageWithSender.sender.avatar || null,
        userId: senderId,
      };
    }

    // 兜底：从群成员列表查找
    const member = groupMembers.find(m => m.user_id === senderId);
    if (member) {
      return {
        nickname: member.nickname || member.user?.nickname || '用户',
        avatar: member.user?.avatar || null,
        userId: member.user_id,
      };
    }

    return {
      nickname: '用户',
      avatar: null,
      userId: senderId,
    };
  }, [currentUserId, currentUser, messages, groupMembers]);

  // 创建消息映射（用于查找被回复的消息）
  const messageMap = useMemo(() => {
    const map = new Map<string, GroupMessage>();
    messages.forEach(msg => {
      map.set(String(msg.id), msg);
    });
    return map;
  }, [messages]);

  // 选择@用户
  const handleSelectMention = useCallback((member: { user_id: string; nickname?: string; user?: { nickname?: string } }) => {
    const lastAtIndex = inputText.lastIndexOf('@');
    if (lastAtIndex !== -1) {
      const textBeforeAt = inputText.slice(0, lastAtIndex);
      const displayName = member.nickname || member.user?.nickname || '用户';
      const newText = `${textBeforeAt}@${displayName} `;
      setInputText(newText);

      if (!selectedMentions.includes(member.user_id)) {
        setSelectedMentions(prev => [...prev, member.user_id]);
      }
    }
    setActivePanel('none');
    setMentionQuery('');

    setTimeout(() => {
      textInputRef.current?.focus();
    }, 100);
  }, [inputText, selectedMentions]);

  // @所有人
  const handleMentionAll = useCallback(() => {
    const lastAtIndex = inputText.lastIndexOf('@');
    if (lastAtIndex !== -1) {
      const textBeforeAt = inputText.slice(0, lastAtIndex);
      const newText = `${textBeforeAt}@所有人 `;
      setInputText(newText);
      setMentionAll(true);
    }
    setActivePanel('none');
    setMentionQuery('');

    setTimeout(() => {
      textInputRef.current?.focus();
    }, 100);
  }, [inputText]);

  /**
   * 构建文本消息的 segments 数组
   */
  const buildTextSegments = useCallback((text: string, replyToMessage?: GroupMessage | null): MessageSegment[] => {
    const segments: MessageSegment[] = [];

    if (replyToMessage) {
      segments.push({
        type: 'reply',
        data: { id: replyToMessage.id, seq: replyToMessage.seq } as ReplySegmentData
      });
    }

    if (mentionAll) {
      segments.push({
        type: 'at',
        data: { user_id: 'all' } as AtSegmentData
      });
    }

    if (selectedMentions.length > 0) {
      selectedMentions.forEach(userId => {
        segments.push({
          type: 'at',
          data: { user_id: userId } as AtSegmentData
        });
      });
    }

    let strippedText = text;
    if (mentionAll) {
      strippedText = strippedText.replace(/@所有人\s*/g, '');
    }
    if (selectedMentions.length > 0) {
      selectedMentions.forEach(userId => {
        const member = groupMembers.find(m => m.user_id === userId);
        const nickname = member?.nickname || member?.user?.nickname || '用户';
        const escapedName = nickname.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        strippedText = strippedText.replace(new RegExp(`@${escapedName}\s*`, 'g'), '');
      });
    }
    strippedText = strippedText.trim();

    if (strippedText) {
      segments.push({
        type: 'text',
        data: { text: strippedText } as TextSegmentData
      });
    }

    return segments;
  }, [mentionAll, selectedMentions, groupMembers]);

  /**
   * 构建图片消息的 segments 数组
   */
  const buildImageSegments = useCallback((imageUrl: string, thumbnailUrl?: string, width?: number, height?: number, replyToMessage?: GroupMessage | null): MessageSegment[] => {
    const segments: MessageSegment[] = [];

    if (replyToMessage) {
      segments.push({
        type: 'reply',
        data: { id: replyToMessage.id, seq: replyToMessage.seq } as ReplySegmentData
      });
    }

    segments.push({
      type: 'image',
      data: {
        url: imageUrl,
        thumbnail_url: thumbnailUrl || imageUrl,
        width: width,
        height: height,
      } as ImageSegmentData
    });

    return segments;
  }, []);

  // 【新架构】发送消息（支持纯文字、纯多图、图文同条）
  const handleSend = useCallback(async () => {
    const trimmedText = inputText.trim();
    const hasPending = pendingAttachments.length > 0;
    if ((!trimmedText && !hasPending) || !conversationId) return;

    if (isGroupChat && isMuted) {
      if (muteAll) {
        Alert.alert('无法发送', '当前群组已开启全员禁言');
      } else {
        Alert.alert('无法发送', '你已被管理员禁言');
      }
      return;
    }

    if (!isGroupChat) {
      if (trimmedText && !canSendFirstPrivateText) {
        Alert.alert('无法发送', '对方未关注你前，仅允许发送一条消息');
        return;
      }
      if (hasPending && !canSendPrivateImage) {
        Alert.alert('无法发送', '对方未关注你前，暂不支持发送图片');
        return;
      }
    }

    const uploadedUrls: string[] = [];
    if (hasPending) {
      setUploadingAttachments(true);
      try {
        const results = await Promise.all(
          pendingAttachments.map(p =>
            uploadService.uploadChatImage({ uri: p.uri, type: p.mimeType })
          )
        );
        for (let i = 0; i < results.length; i++) {
          const r = results[i];
          if (!r?.url) {
            Alert.alert('上传失败', `第 ${i + 1} 张图片上传失败，请重试`);
            return;
          }
          uploadedUrls.push(r.url);
        }
      } catch (error) {
        console.error('上传图片失败:', error);
        Alert.alert('上传失败', getSendErrorMessage(error, '图片上传失败，请重试'));
        return;
      } finally {
        setUploadingAttachments(false);
      }
    }

    setSending(true);

    try {
      const segments: MessageSegment[] = [...buildTextSegments(trimmedText, replyingTo)];
      for (const url of uploadedUrls) {
        segments.push({
          type: 'image',
          data: {
            url,
            thumbnail_url: url,
          } as ImageSegmentData,
        });
      }

      if (segments.length === 0) {
        Alert.alert('无法发送', '消息内容为空');
        return;
      }

      if (isGroupChat && routeGroupId) {
        await messageService.sendMessageByAction('group', conversationId, segments);

        setInputText('');
        setSelectedMentions([]);
        setMentionAll(false);
        setReplyingTo(null);
        setPendingAttachments([]);
      } else {
        await sendMessageViaManager(segments);
        setInputText('');
        setSelectedMentions([]);
        setMentionAll(false);
        setReplyingTo(null);
        setPendingAttachments([]);
      }

      setTimeout(() => {
        scrollToLatest(false, false, hasPending ? 'send-mixed' : 'send-text');
      }, 100);
    } catch (error) {
      console.error('发送消息失败:', error);
      Alert.alert('发送失败', getSendErrorMessage(error, '消息发送失败，请重试'));
    } finally {
      setSending(false);
    }
  }, [
    inputText,
    pendingAttachments,
    conversationId,
    isGroupChat,
    routeGroupId,
    sendMessageViaManager,
    isMuted,
    muteAll,
    buildTextSegments,
    replyingTo,
    getSendErrorMessage,
    canSendFirstPrivateText,
    canSendPrivateImage,
    scrollToLatest,
  ]);

  // 选择图片（多选进入输入框待发送，点发送时与文字一并发出）
  const handlePickImage = useCallback(async () => {
    if (pendingAttachments.length >= MAX_PENDING_CHAT_IMAGES) {
      Alert.alert('提示', `最多添加 ${MAX_PENDING_CHAT_IMAGES} 张图片`);
      setActivePanel('none');
      return;
    }

    try {
      const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();

      if (status !== 'granted') {
        Alert.alert('权限不足', '需要访问相册权限才能选择图片');
        return;
      }

      const remaining = MAX_PENDING_CHAT_IMAGES - pendingAttachments.length;

      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: 'images',
        allowsEditing: false,
        quality: 1,
        allowsMultipleSelection: true,
        selectionLimit: remaining,
      });

      if (!result.canceled && result.assets && result.assets.length > 0) {
        const newItems: PendingChatAttachment[] = result.assets.map((asset, i) => ({
          id: `${Date.now()}-${i}-${Math.random().toString(36).slice(2, 9)}`,
          uri: asset.uri,
          mimeType: asset.mimeType ?? undefined,
        }));
        setPendingAttachments(prev => [...prev, ...newItems].slice(0, MAX_PENDING_CHAT_IMAGES));
      }
    } catch (error) {
      console.error('选择图片失败:', error);
      Alert.alert('错误', '选择图片失败');
    }

    setActivePanel('none');
  }, [pendingAttachments.length]);

  // 拍摄照片（加入待发送队列）
  const handleTakePhoto = useCallback(async () => {
    if (pendingAttachments.length >= MAX_PENDING_CHAT_IMAGES) {
      Alert.alert('提示', `最多添加 ${MAX_PENDING_CHAT_IMAGES} 张图片`);
      setActivePanel('none');
      return;
    }

    try {
      const { status } = await ImagePicker.requestCameraPermissionsAsync();

      if (status !== 'granted') {
        Alert.alert('权限不足', '需要相机权限才能拍摄照片');
        return;
      }

      const result = await ImagePicker.launchCameraAsync({
        mediaTypes: 'images',
        allowsEditing: false,
        quality: 0.8,
      });

      if (!result.canceled && result.assets && result.assets.length > 0) {
        const asset = result.assets[0];
        setPendingAttachments(prev =>
          prev.length >= MAX_PENDING_CHAT_IMAGES
            ? prev
            : [
                ...prev,
                {
                  id: `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
                  uri: asset.uri,
                  mimeType: asset.mimeType ?? undefined,
                },
              ]
        );
      }
    } catch (error) {
      console.error('拍摄照片失败:', error);
      Alert.alert('错误', '拍摄照片失败');
    }

    setActivePanel('none');
  }, [pendingAttachments.length]);

  // 处理更多功能
  const handleMoreAction = useCallback((actionId: string) => {
    switch (actionId) {
      case 'image':
        handlePickImage();
        break;
      case 'camera':
        handleTakePhoto();
        break;
      case 'file':
        Alert.alert('提示', '文件功能即将上线');
        setActivePanel('none');
        break;
      case 'location':
        Alert.alert('提示', '位置功能即将上线');
        setActivePanel('none');
        break;
      default:
        setActivePanel('none');
    }
  }, [handlePickImage, handleTakePhoto]);

  // 插入表情
  const handleInsertEmoji = useCallback((emoji: string) => {
    setInputText(prev => prev + emoji);
  }, []);

  // 发送自定义表情
  const handleSendSticker = useCallback(async (stickerUrl: string) => {
    if (!conversationId) return;

    if (isGroupChat && isMuted) {
      if (muteAll) {
        Alert.alert('无法发送', '当前群组已开启全员禁言');
      } else {
        Alert.alert('无法发送', '你已被管理员禁言');
      }
      return;
    }

    if (!isGroupChat && !canSendPrivateImage) {
      Alert.alert('无法发送', '对方未关注你前，暂不支持发送图片');
      return;
    }

    setSendingImage(true);

    try {
      const segments = buildImageSegments(stickerUrl, stickerUrl, undefined, undefined, replyingTo);

      if (isGroupChat && routeGroupId) {
        await messageService.sendMessageByAction('group', conversationId, segments);
        setReplyingTo(null);
      } else {
        // 【新架构】私聊表情通过 MessageManager 发送
        await sendMessageViaManager(segments);
        setReplyingTo(null);
      }

      setTimeout(() => {
        scrollToLatest(false, false, 'send-sticker');
      }, 100);
    } catch (error) {
      console.error('发送自定义表情失败:', error);
      Alert.alert('发送失败', '自定义表情发送失败，请重试');
    } finally {
      setSendingImage(false);
    }
  }, [conversationId, isGroupChat, routeGroupId, sendMessageViaManager, isMuted, muteAll, buildImageSegments, replyingTo, canSendPrivateImage, scrollToLatest]);

  // 切换表情面板
  const toggleEmojiPanel = useCallback(() => {
    Keyboard.dismiss();
    setActivePanel(prev => {
      const newPanel = prev === 'emoji' ? 'none' : 'emoji';
      return newPanel;
    });
  }, []);

  // 切换更多功能面板
  const toggleMorePanel = useCallback(() => {
    Keyboard.dismiss();
    setActivePanel(prev => {
      const newPanel = prev === 'more' ? 'none' : 'more';
      return newPanel;
    });
  }, []);

  // 关闭面板
  const closePanel = useCallback(() => {
    setActivePanel('none');
  }, []);

  // 撤回消息 - 现在通过 MessageManager 处理
  const handleRecall = useCallback(async (messageId: string) => {
    try {
      if (isGroupChat && routeGroupId) {
        await messageService.recallMessage(messageId);
      } else {
        await messageService.recallMessage(messageId);
      }
      // 不需要手动更新状态，MessageManager 会处理撤回事件
    } catch (error) {
      console.error('撤回消息失败:', error);
      Alert.alert('撤回失败', '无法撤回消息');
    }
  }, [isGroupChat, routeGroupId, conversationId]);

  // 长按消息显示操作菜单
  const handleLongPressMessage = useCallback((message: GroupMessage, position?: MenuPosition) => {
    const isSystemNotice = message.is_system_notice || message.category === 'notification';
    if (message.status === 'recalled' || isSystemNotice) return;
    setSelectedMessage(message);
    setSelectedMessageId(String(message.id));
    setMenuPosition(position);
    setLongPressMenuVisible(true);
  }, []);

  // 隐藏长按菜单
  const hideLongPressMenu = useCallback(() => {
    setLongPressMenuVisible(false);
    setSelectedMessage(null);
    setSelectedMessageId(null);
    setMenuPosition(undefined);
  }, []);

  // 删除消息
  const handleDeleteMessage = useCallback(async (messageId: string) => {
    try {
      await messageService.deleteMessage(messageId);
      // 从本地状态移除（MessageManager 不会自动处理删除）
      const updatedMessages = messages.filter(m => m.id !== messageId);
      // 注意：这里我们依赖 MessageManager 的数据，所以需要通过其他方式刷新
      // 暂时只删除本地数据库
      await deleteMessageFromDb(messageId);
    } catch (error) {
      console.error('删除消息失败:', error);
      Alert.alert('删除失败', '无法删除消息');
    }
  }, [messages]);

  // 清空会话的所有聊天记录
  const handleClearConversation = useCallback(async () => {
    if (!conversationId) return;

    try {
      setLastSeq(0);
      setFirstSeq(0);
      setHasMoreHistory(true);
      await clearConversationMessages(conversationId);
      // 刷新消息列表
      await refreshMessages();
    } catch (error) {
      console.error('清空会话失败:', error);
      Alert.alert('清空失败', '无法清空聊天记录');
    }
  }, [conversationId, refreshMessages]);

  // 回复消息
  const handleReplyMessage = useCallback((message: GroupMessage) => {
    setReplyingTo(message);
    textInputRef.current?.focus();
    hideLongPressMenu();
  }, [hideLongPressMenu]);

  // 取消回复
  const handleCancelReply = useCallback(() => {
    setReplyingTo(null);
  }, []);

  // 点击头像跳转到用户主页
  const handleAvatarPress = useCallback((userId: string) => {
    if (userId && userId !== currentUserId) {
      router.push(hrefs.hrefUserProfile(String(userId)));
    }
  }, [currentUserId]);

  // 长按头像@用户
  const handleAvatarLongPress = useCallback((senderId: string, nickname: string) => {
    if (!isGroupChat || senderId === currentUserId) return;

    if (!selectedMentions.includes(senderId)) {
      setSelectedMentions(prev => [...prev, senderId]);
    }

    const newText = inputText + `@${nickname} `;
    setInputText(newText);

    setTimeout(() => {
      textInputRef.current?.focus();
    }, 100);
  }, [isGroupChat, currentUserId, inputText, selectedMentions]);

  // 获取正在输入提示文本 - 现在从 MessageManager 获取
  const getTypingHint = useCallback((): string | null => {
    if (groupTypingUsers.length === 0) return null;

    const typingNames = groupTypingUsers.map(userId => {
      const member = groupMembers.find(m => m.user_id === userId);
      return member?.nickname || member?.user?.nickname || '有人';
    });

    if (typingNames.length === 1) {
      return `${typingNames[0]} 正在输入...`;
    } else if (typingNames.length <= 3) {
      return `${typingNames.join('、')} 正在输入...`;
    } else {
      return `${typingNames.slice(0, 3).join('、')}等 ${groupTypingUsers.length} 人正在输入...`;
    }
  }, [groupTypingUsers, groupMembers]);

  // 计算底部面板高度
  const getPanelHeight = useCallback(() => {
    if (activePanel === 'none') return 0;
    if (activePanel === 'mention') return 250;
    return 350;
  }, [activePanel]);

  // 计算输入框的bottom值
  const getInputBottom = useCallback(() => {
    if (keyboardHeight > 0) return keyboardHeight;
    if (activePanel !== 'none') return getPanelHeight();
    return 0;
  }, [keyboardHeight, activePanel, getPanelHeight]);

  // 计算消息列表的底部padding
  const getListPaddingBottom = useCallback(() => {
    if (activePanel !== 'none' && keyboardHeight === 0) return getPanelHeight();
    return 0;
  }, [keyboardHeight, activePanel, getPanelHeight]);

  // 关闭所有面板
  const handleDismiss = useCallback(() => {
    if (activePanel !== 'none') {
      Keyboard.dismiss();
      setActivePanel('none');
    }
  }, [activePanel]);

  // 导航到群组信息或用户资料
  const navigateToInfo = useCallback(() => {
    if (isGroupChat && routeGroupId) {
      router.push(hrefs.hrefGroupInfo(routeGroupId, conversationId || undefined));
    } else if (otherUser?.id) {
      router.push(hrefs.hrefUserProfile(String(otherUser.id)));
    }
  }, [isGroupChat, routeGroupId, otherUser, conversationId]);

  // 导航到聊天管理页面
  const navigateToChatSettings = useCallback(() => {
    if (isGroupChat && routeGroupId) {
      router.push(hrefs.hrefGroupInfo(routeGroupId, conversationId || undefined));
    } else if (otherUser?.id && conversationId) {
      router.push(
        hrefs.hrefPrivateChatInfo({
          conversationId,
          userId: String(otherUser.id),
          userName: otherUser.nickname,
          userAvatar: otherUser.avatar,
        })
      );
    }
  }, [isGroupChat, routeGroupId, otherUser, conversationId]);

  return {
    // 状态
    messages,
    conversationId,
    inputText,
    otherUser,
    currentUser,
    currentUserId,
    keyboardHeight,
    loading,
    sending,
    activePanel,
    sendingImage,
    uploadingAttachments,
    pendingAttachments,
    isComposerBusy,
    replyingTo,
    longPressMenuVisible,
    selectedMessage,
    selectedMessageId,
    setSelectedMessageId,
    menuPosition,
    isGroupChat,
    groupInfo,
    groupMembers,
    // 【改造】使用 MessageManager 的输入状态
    typingUsers: groupTypingUsers,
    currentUserRole,
    mentionQuery,
    selectedMentions,
    isMuted,
    muteAll,
    followRestrictionHint,
    canSendPrivateImage,
    routeGroupId,
    routeGroupName,
    otherUserLastReadSeq,
    messageMap,
    loadingMore,
    hasMoreHistory,

    // Refs
    flatListRef,
    textInputRef,
    scrollPositionRef,

    // 方法
    formatTime,
    shouldShowTime,
    handleInputChange,
    handleSend,
    handlePickImage,
    removePendingAttachment,
    handleTakePhoto,
    handleMoreAction,
    handleInsertEmoji,
    handleSendSticker,
    toggleEmojiPanel,
    toggleMorePanel,
    closePanel,
    handleRecall,
    handleLongPressMessage,
    hideLongPressMenu,
    handleDeleteMessage,
    handleReplyMessage,
    handleCancelReply,
    handleAvatarPress,
    handleAvatarLongPress,
    handleSelectMention,
    handleMentionAll,
    getSenderInfo,
    getTypingHint,
    getPanelHeight,
    getInputBottom,
    getListPaddingBottom,
    handleDismiss,
    navigateToInfo,
    navigateToChatSettings,
    loadMoreHistory,
    handleClearConversation,
    handleMessageListContentSizeChange,
    handleReachLatestEdge,
    jumpToLatestMessages,
    setBrowsingHistory,
  };
};
