/**
 * 聊天页 ChatScreen
 * 胡萝卜BBS - 私信/群聊聊天界面
 * 高级现代化设计
 * 支持群聊功能：显示发送者头像和昵称、@提及功能
 * 支持响应式布局（桌面端宽屏优化）
 * 
 * 重构说明：将原2264行的大文件拆分为多个模块化组件
 * - types.ts: 类型定义
 * - constants.ts: 常量定义
 * - styles.ts: 样式定义
 * - useChatScreen.ts: 自定义Hook，管理所有状态和逻辑
 * - EmojiPanel.tsx: 表情面板组件
 * - MorePanel.tsx: 更多功能面板组件
 * - MentionPanel.tsx: @成员选择面板组件
 * - LongPressMenu.tsx: 长按菜单组件
 * - ChatHeader.tsx: 聊天头部组件
 * - MessageBubble.tsx: 消息气泡组件
 * - ChatInput.tsx: 输入框组件
 */

import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import {
  View,
  FlatList,
  ActivityIndicator,
  KeyboardAvoidingView,
  Platform,
  TouchableOpacity,
} from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { useNavigation, useRouter } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { Text, ImageGallery, ImageGridItem } from '../../components/common';
import { useAppColors } from '../../theme';
import * as hrefs from '../../navigation/hrefs';
import { messageManager } from '../../stores';
import { useBreakpointGTE } from '../../hooks/useResponsive';
import {
  useChatScreen,
  useChatScreenStyles,
  EmojiPanel,
  MorePanel,
  MentionPanel,
  LongPressMenu,
  ChatHeader,
  MessageBubble,
  ChatInput,
  GroupInfoPanel,
  PANEL_HEIGHTS,
} from './components/ChatScreen';

export const ChatScreen: React.FC = () => {
  const navigation = useNavigation();
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const colors = useAppColors();
  const styles = useChatScreenStyles();

  // 响应式布局
  const isWideScreen = useBreakpointGTE('lg');

  // 监听屏幕宽度变化，当变为大屏幕时自动跳转到web端首页
  useEffect(() => {
    if (isWideScreen) {
      router.replace(hrefs.hrefHome());
    }
  }, [isWideScreen, router]);
  
  // 输入框区域高度（用于定位浮动 mention 面板）
  const [inputWrapperHeight, setInputWrapperHeight] = useState(60);
  const [showEdgeLoadingIndicator, setShowEdgeLoadingIndicator] = useState(false);
  const replyTargetMessageIdRef = useRef<string | null>(null);
  const replyHighlightTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const isPreloadingRef = useRef(false);
  const lastScrollYRef = useRef(0);
  const isUserDraggingRef = useRef(false);
  const historyAnchorRef = useRef<{ active: boolean; beforeY: number; beforeHeight: number }>({
    active: false,
    beforeY: 0,
    beforeHeight: 0,
  });
  const preloadCooldownTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const showJumpToLatestRef = useRef(false);
  const [showJumpToLatest, setShowJumpToLatest] = useState(false);

  const containerStyle = useMemo(() => ([
    styles.container,
    isWideScreen ? { maxWidth: 1200, alignSelf: 'center' as const, width: '100%' as const } : null,
  ]), [isWideScreen, styles.container]);

  const listContentStyle = useMemo(() => ([
    styles.listContent,
    isWideScreen
      ? { paddingHorizontal: 24, maxWidth: 900, alignSelf: 'center' as const }
      : { paddingHorizontal: 16 },
  ]), [isWideScreen, styles.listContent]);

  const inputWrapperStyle = useMemo(() => ([
    styles.inputWrapper,
    isWideScreen ? { maxWidth: 900, alignSelf: 'center' as const, width: '100%' as const } : null,
  ]), [isWideScreen, styles.inputWrapper]);

  // 图片查看器状态
  const [showImageViewer, setShowImageViewer] = useState(false);
  const [chatImages, setChatImages] = useState<ImageGridItem[]>([]);
  const [selectedImageIndex, setSelectedImageIndex] = useState(0);

  // 图片点击处理函数
  const handleImagePress = (images: ImageGridItem[], index: number) => {
    setChatImages(images);
    setSelectedImageIndex(index);
    setShowImageViewer(true);
  };
  
  // 关闭图片查看器
  const handleCloseImageViewer = () => {
    setShowImageViewer(false);
  };
  
  // 群信息面板状态
  const [showGroupInfoPanel, setShowGroupInfoPanel] = useState(false);
  
  // 打开群信息面板
  const handleGroupInfoPress = useCallback(() => {
    setShowGroupInfoPanel(true);
  }, []);
  
  // 关闭群信息面板
  const handleCloseGroupInfoPanel = useCallback(() => {
    setShowGroupInfoPanel(false);
  }, []);
  
  const {
    // 状态
    messages,
    inputText,
    otherUser,
    currentUser,
    currentUserId,
    keyboardHeight,
    loading,
    isComposerBusy,
    activePanel,
    sendingImage,
    uploadingAttachments,
    pendingAttachments,
    replyingTo,
    longPressMenuVisible,
    selectedMessage,
    selectedMessageId,
    setSelectedMessageId,
    menuPosition,
    isGroupChat,
    groupInfo,
    groupMembers,
    currentUserRole,
    mentionQuery,
    isMuted,
    muteAll,
    followRestrictionHint,
    canSendPrivateImage,
    routeGroupId,
    routeGroupName,
    otherUserLastReadSeq,
    messageMap,
    loadingMore,
    hasMoreHistory,
    conversationId,

    // Refs
    flatListRef,
    textInputRef,
    scrollPositionRef,

    // 方法
    formatTime,
    shouldShowTime,
    handleInputChange,
    handleSend,
    removePendingAttachment,
    handleMoreAction,
    handleInsertEmoji,
    handleSendSticker,
    toggleEmojiPanel,
    toggleMorePanel,
    closePanel,
    handleRecall,
    handleLongPressMessage,
    hideLongPressMenu,
    handleDeleteMessage,
    handleReplyMessage,
    handleCancelReply,
    handleAvatarPress,
    handleAvatarLongPress,
    handleSelectMention,
    handleMentionAll,
    getSenderInfo,
    getTypingHint,
    getInputBottom,
    handleDismiss,
    navigateToInfo,
    navigateToChatSettings,
    loadMoreHistory,
    handleMessageListContentSizeChange,
    handleReachLatestEdge,
    jumpToLatestMessages,
    setBrowsingHistory,
  } = useChatScreen();
  const displayMessages = useMemo(() => [...messages].reverse(), [messages]);

  useEffect(() => {
    if (!loadingMore && showEdgeLoadingIndicator) {
      setShowEdgeLoadingIndicator(false);
    }
  }, [loadingMore, showEdgeLoadingIndicator]);

  useEffect(() => {
    if (loading) {
      showJumpToLatestRef.current = false;
      setShowJumpToLatest(false);
    }
  }, [loading]);

  useEffect(() => {
    showJumpToLatestRef.current = false;
    setShowJumpToLatest(false);
  }, [conversationId]);

  useEffect(() => {
    return () => {
      if (preloadCooldownTimerRef.current) {
        clearTimeout(preloadCooldownTimerRef.current);
      }
      if (replyHighlightTimerRef.current) {
        clearTimeout(replyHighlightTimerRef.current);
      }
    };
  }, []);

  const handleReplyPreviewPress = useCallback((messageId: string) => {
    const targetId = String(messageId);
    const targetIndex = displayMessages.findIndex(msg => String(msg.id) === targetId);
    if (targetIndex < 0) return;

    replyTargetMessageIdRef.current = targetId;
    setBrowsingHistory(true);

    flatListRef.current?.scrollToIndex({
      index: targetIndex,
      animated: true,
      viewPosition: 0.5,
    });
  }, [displayMessages, flatListRef, setBrowsingHistory]);

  // 监听返回事件，刷新会话列表
  useEffect(() => {
    const unsubscribe = navigation.addListener('beforeRemove', () => {
      // 刷新会话列表，确保已读状态正确显示
      messageManager.requestConversationListRefresh('chat-before-remove', {
        force: true,
        allowDefer: false,
      });
    });
    return unsubscribe;
  }, [navigation]);

  // 渲染消息气泡
  const messageIndexMap = useMemo(() => {
    const map = new Map<string, number>();
    messages.forEach((msg, idx) => {
      map.set(String(msg.id), idx);
    });
    return map;
  }, [messages]);

  const renderMessage = useCallback(({ item, index }: { item: any; index: number }) => {
    // inverted 下 renderItem 的 index 与时间顺序不一致，需回查原始序索引
    const logicalIndex = messageIndexMap.get(String(item.id)) ?? index;
    return (
      <MessageBubble
        message={item}
        index={logicalIndex}
        currentUserId={currentUserId}
        currentUser={currentUser}
        otherUser={otherUser}
        isGroupChat={isGroupChat}
        groupMembers={groupMembers}
        otherUserLastReadSeq={otherUserLastReadSeq}
        selectedMessageId={selectedMessageId}
        messageMap={messageMap}
        onLongPress={handleLongPressMessage}
        onAvatarPress={handleAvatarPress}
        onAvatarLongPress={handleAvatarLongPress}
        formatTime={formatTime}
        shouldShowTime={shouldShowTime}
        onImagePress={handleImagePress}
        onReply={handleReplyMessage}
        onReplyPress={handleReplyPreviewPress}
      />
    );
  }, [
    messageIndexMap,
    currentUserId,
    currentUser,
    otherUser,
    isGroupChat,
    groupMembers,
    otherUserLastReadSeq,
    selectedMessageId,
    messageMap,
    handleLongPressMessage,
    handleAvatarPress,
    handleAvatarLongPress,
    formatTime,
    shouldShowTime,
    handleImagePress,
    handleReplyMessage,
    handleReplyPreviewPress,
  ]);

  const keyExtractor = useCallback((item: any) => String(item.id), []);

  // 获取正在输入提示
  const typingHint = getTypingHint();
  const handleMessageListScroll = useCallback((event: any) => {
    const { contentSize, contentOffset, layoutMeasurement } = event.nativeEvent;
    scrollPositionRef.current = {
      contentHeight: contentSize.height,
      scrollY: contentOffset.y,
      viewportHeight: layoutMeasurement.height,
    };

    // inverted：offset 越大离最新消息端越远，与 setBrowsingHistory(120) 阈值一致
    const shouldShowJump =
      contentOffset.y > 120 && !loading && messages.length > 0;
    if (showJumpToLatestRef.current !== shouldShowJump) {
      showJumpToLatestRef.current = shouldShowJump;
      setShowJumpToLatest(shouldShowJump);
    }

    // 离开最新消息端后进入“浏览历史”模式，屏蔽自动跟随到底
    if (contentOffset.y > 120) {
      setBrowsingHistory(true);
    }

    // 仅用户手势主动回到底部时才解除历史阅读锁（避免加载阶段误解锁）
    const isScrollingTowardLatest = contentOffset.y < lastScrollYRef.current;
    if (
      isUserDraggingRef.current &&
      !loadingMore &&
      isScrollingTowardLatest &&
      contentOffset.y <= 40
    ) {
      handleReachLatestEdge();
    }

    // inverted 下历史端在“列表尾部”，对应 offset 增大且距离尾部变小
    const distanceToHistoryEdge = contentSize.height - (contentOffset.y + layoutMeasurement.height);
    lastScrollYRef.current = contentOffset.y;

    // 预加载阈值：按屏幕高度动态提前（至少 420），确保边界前开始加载
    const PRELOAD_HISTORY_THRESHOLD = Math.max(420, layoutMeasurement.height * 1.2);
    // 仅在真正接近边界时才显示旋转提示
    const EDGE_LOADING_INDICATOR_THRESHOLD = 60;
    const shouldShowEdgeIndicator = loadingMore && distanceToHistoryEdge <= EDGE_LOADING_INDICATOR_THRESHOLD;
    if (shouldShowEdgeIndicator !== showEdgeLoadingIndicator) {
      setShowEdgeLoadingIndicator(shouldShowEdgeIndicator);
    }

    if (
      distanceToHistoryEdge <= PRELOAD_HISTORY_THRESHOLD &&
      hasMoreHistory &&
      !loadingMore &&
      !loading &&
      !isPreloadingRef.current
    ) {
      isPreloadingRef.current = true;
      loadMoreHistory().finally(() => {
        if (preloadCooldownTimerRef.current) {
          clearTimeout(preloadCooldownTimerRef.current);
        }
        preloadCooldownTimerRef.current = setTimeout(() => {
          isPreloadingRef.current = false;
        }, 350);
      });
    }
  }, [
    scrollPositionRef,
    hasMoreHistory,
    loadingMore,
    loading,
    messages.length,
    loadMoreHistory,
    handleReachLatestEdge,
    showEdgeLoadingIndicator,
    setBrowsingHistory,
  ]);

  const handleContentSizeChange = useCallback((contentWidth: number, contentHeight: number) => {
    handleMessageListContentSizeChange(contentWidth, contentHeight);
  }, [handleMessageListContentSizeChange]);

  return (
    <SafeAreaView style={containerStyle} edges={['top']}>
      <KeyboardAvoidingView
        style={styles.container}
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}
        keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 0}
      >
        <StatusBar style="dark" backgroundColor="#FFFFFF" />
      
      {/* 顶部栏 */}
      <ChatHeader
        isGroupChat={isGroupChat}
        groupInfo={groupInfo}
        otherUser={otherUser}
        routeGroupName={routeGroupName}
        typingHint={typingHint}
        onBack={() => router.back()}
        onTitlePress={navigateToInfo}
        onMorePress={navigateToChatSettings}
        onGroupInfoPress={handleGroupInfoPress}
        isWideScreen={isWideScreen}
      />

      {/* 消息列表 */}
      <View
        style={styles.messageListContainer}
        onLayout={e => {
          scrollPositionRef.current.viewportHeight = e.nativeEvent.layout.height;
        }}
        onTouchEnd={handleDismiss}
      >
        {loading ? (
          <View style={styles.loadingContainer}>
            <ActivityIndicator size="large" color={colors.primary.main} />
          </View>
        ) : (
          <FlatList
            ref={flatListRef}
            inverted
            data={displayMessages}
            renderItem={renderMessage}
            keyExtractor={keyExtractor}
            contentContainerStyle={listContentStyle as any}
            showsVerticalScrollIndicator={false}
            keyboardShouldPersistTaps="handled"
            initialNumToRender={14}
            maxToRenderPerBatch={10}
            updateCellsBatchingPeriod={50}
            windowSize={15}
            removeClippedSubviews={false}
            onScroll={handleMessageListScroll}
            onScrollBeginDrag={() => {
              isUserDraggingRef.current = true;
              handleDismiss();
            }}
            onScrollEndDrag={() => {
              isUserDraggingRef.current = false;
            }}
            onMomentumScrollEnd={() => {
              isUserDraggingRef.current = false;
            }}
            scrollEventThrottle={16}
            onContentSizeChange={handleContentSizeChange}
            onScrollToIndexFailed={(info) => {
              const targetId = replyTargetMessageIdRef.current;
              if (!targetId || !flatListRef.current) return;

              flatListRef.current.scrollToOffset({
                offset: Math.max(0, info.averageItemLength * info.index),
                animated: true,
              });

              setTimeout(() => {
                const retryIndex = displayMessages.findIndex(msg => String(msg.id) === targetId);
                if (retryIndex >= 0) {
                  flatListRef.current?.scrollToIndex({
                    index: retryIndex,
                    animated: true,
                    viewPosition: 0.5,
                  });
                }
              }, 120);
            }}
          />
        )}
        {showEdgeLoadingIndicator && (
          <View
            pointerEvents="none"
            style={{
              position: 'absolute',
              top: 8,
              left: 0,
              right: 0,
              alignItems: 'center',
            }}
          >
            <View
              style={{
                backgroundColor: 'rgba(255,255,255,0.9)',
                borderRadius: 12,
                paddingHorizontal: 10,
                paddingVertical: 6,
              }}
            >
              <ActivityIndicator size="small" color={colors.primary.main} />
            </View>
          </View>
        )}
        {showJumpToLatest && (
          <TouchableOpacity
            style={styles.jumpToLatestFab}
            onPress={jumpToLatestMessages}
            activeOpacity={0.85}
            accessibilityRole="button"
            accessibilityLabel="回到最新消息"
          >
            <MaterialCommunityIcons name="chevron-down" size={20} color={colors.primary.main} />
            <Text style={styles.jumpToLatestFabText}>最新消息</Text>
          </TouchableOpacity>
        )}
      </View>

      {/* 底部区域：输入框 + 面板 */}
      <View style={{ marginBottom: keyboardHeight > 0 ? keyboardHeight : 0 }}>
        {/* 输入框区域 */}
        <View
          style={[inputWrapperStyle, insets.bottom > 0 && { paddingBottom: insets.bottom }]}
          onLayout={e => setInputWrapperHeight(e.nativeEvent.layout.height)}
        >
          <ChatInput
            inputText={inputText}
            onInputChange={handleInputChange}
            onSend={handleSend}
            onToggleEmoji={toggleEmojiPanel}
            onToggleMore={toggleMorePanel}
            activePanel={activePanel}
            isComposerBusy={isComposerBusy}
            isMuted={isMuted}
            isGroupChat={isGroupChat}
            muteAll={muteAll}
            restrictionHint={followRestrictionHint}
            replyingTo={replyingTo}
            pendingAttachments={pendingAttachments}
            onRemovePendingAttachment={removePendingAttachment}
            onCancelReply={handleCancelReply}
            onFocus={() => {
              // 输入框获得焦点时，关闭其他面板（但不要关闭键盘）
              if (activePanel !== 'none' && activePanel !== 'mention') {
                closePanel();
              }
            }}
            currentUser={currentUser}
            otherUser={otherUser}
            getSenderInfo={getSenderInfo}
          />
        </View>

        {/* 表情面板 */}
        {activePanel === 'emoji' && keyboardHeight === 0 && (
          <View style={[styles.panelWrapper, styles.emojiPanelWrapper, { height: PANEL_HEIGHTS.emoji + insets.bottom, paddingBottom: insets.bottom }]}>
            <EmojiPanel
              onInsertEmoji={handleInsertEmoji}
              onInsertSticker={handleSendSticker}
              onClose={closePanel}
            />
          </View>
        )}

        {/* 更多功能面板 */}
        {activePanel === 'more' && keyboardHeight === 0 && (
          <View style={[styles.panelWrapper, { height: PANEL_HEIGHTS.more + insets.bottom, paddingBottom: insets.bottom }]}>
            <MorePanel
              onAction={handleMoreAction}
              disabledActionIds={!isGroupChat && !canSendPrivateImage ? ['image', 'camera'] : []}
            />
          </View>
        )}
      </View>

      {/* 发送图片加载遮罩 */}
      {(sendingImage || uploadingAttachments) && (
        <View style={styles.overlay}>
          <View style={styles.overlayContent}>
            <ActivityIndicator size="large" color={colors.primary.main} />
            <Text style={styles.overlayText}>
              {uploadingAttachments ? '正在上传图片…' : '发送图片中…'}
            </Text>
          </View>
        </View>
      )}

      {/* @成员选择浮层 - 绝对定位在输入框上方，覆盖消息列表 */}
      {activePanel === 'mention' && (
        <View
          style={[
            styles.mentionPanelFloat,
            {
              bottom: keyboardHeight > 0
                ? keyboardHeight + inputWrapperHeight
                : inputWrapperHeight + (insets.bottom > 0 ? insets.bottom : 0),
              height: PANEL_HEIGHTS.mention,
            },
          ]}
        >
          <MentionPanel
            members={groupMembers}
            currentUserId={currentUserId}
            mentionQuery={mentionQuery}
            currentUserRole={currentUserRole}
            onSelectMention={handleSelectMention}
            onMentionAll={handleMentionAll}
            onClose={closePanel}
          />
        </View>
      )}

      {/* 长按菜单 */}
      <LongPressMenu
        visible={longPressMenuVisible}
        message={selectedMessage}
        currentUserId={currentUserId}
        position={menuPosition}
        onClose={hideLongPressMenu}
        onReply={handleReplyMessage}
        onRecall={handleRecall}
        onDelete={handleDeleteMessage}
      />
      
      {/* 图片查看器 */}
      <ImageGallery
        visible={showImageViewer}
        images={chatImages.map(img => ({
          id: img.id || img.url || String(Math.random()),
          url: img.url || img.uri || ''
        }))}
        initialIndex={selectedImageIndex}
        onClose={handleCloseImageViewer}
        enableSave
      />
      
      {/* 群信息侧边栏面板 - 仅大屏幕显示 */}
        <GroupInfoPanel
          visible={showGroupInfoPanel}
          groupId={routeGroupId ? String(routeGroupId) : undefined}
          groupInfo={groupInfo as any}
          conversationId={conversationId || undefined}
          currentUserId={currentUserId}
          isPinned={false}
          onClose={handleCloseGroupInfoPanel}
          onTogglePin={(pinned) => {
            // TODO: 实现置顶功能
            console.log('Toggle pin:', pinned);
          }}
          onLeaveGroup={() => {
            // TODO: 实现退出群聊功能
            console.log('Leave group');
          }}
          onInviteMembers={() => {
            // TODO: 实现邀请新成员功能
            console.log('Invite members');
          }}
          onViewAllMembers={() => {
            // TODO: 实现查看全部成员功能
            console.log('View all members');
          }}
        />
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
};

export default ChatScreen;
