/**
 * 消息气泡组件
 * 支持消息链（Segment数组）渲染
 * 支持响应式布局（宽屏下优化显示）
 */

import React, { useRef, useMemo, useCallback } from 'react';
import { 
  View, 
  TouchableOpacity, 
  Image, 
  GestureResponderEvent,
  StyleSheet,
  Dimensions,
} from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { Avatar, Text, ImageGridItem } from '../../../../components/common';
import { useChatScreenStyles } from './styles';
import { useResponsive, useBreakpointGTE } from '../../../../hooks/useResponsive';
import { MessageBubbleProps, SenderInfo, MenuPosition, GroupMessage } from './types';
import { MessageSegmentsRenderer } from './SegmentRenderer';
import { MessageSegment, ImageSegmentData, extractTextFromSegments } from '../../../../types/dto';
import { SwipeableMessageBubble } from './SwipeableMessageBubble';
// 获取屏幕宽度
const { width: SCREEN_WIDTH } = Dimensions.get('window');

// 消息内容最大宽度比例
const MAX_WIDTH_RATIO = {
  mobile: 0.75,
  tablet: 0.65,
  desktop: 0.55,
};

export const MessageBubble: React.FC<MessageBubbleProps> = ({
  message,
  index,
  currentUserId,
  currentUser,
  otherUser,
  isGroupChat,
  groupMembers,
  otherUserLastReadSeq,
  selectedMessageId,
  messageMap,
  onLongPress,
  onAvatarPress,
  onAvatarLongPress,
  formatTime,
  shouldShowTime,
  onImagePress,
  onReply,
  onReplyPress,
}) => {
  const bubbleRef = useRef<View>(null);
  const pressPositionRef = useRef({ x: 0, y: 0 });
  const baseStyles = useChatScreenStyles();

  // 响应式布局
  const { width } = useResponsive();
  const isWideScreen = useBreakpointGTE('lg');
  const isTablet = useBreakpointGTE('md');
  
  // 计算消息内容最大宽度
  const maxContentWidth = useMemo(() => {
    const ratio = isWideScreen ? MAX_WIDTH_RATIO.desktop : 
                  isTablet ? MAX_WIDTH_RATIO.tablet : 
                  MAX_WIDTH_RATIO.mobile;
    return Math.min(SCREEN_WIDTH * ratio, 600);
  }, [isWideScreen, isTablet]);
  
  // 合并样式
  const styles = useMemo(() => {
    return StyleSheet.create({
      ...baseStyles,
      messageContent: {
        ...baseStyles.messageContent,
        maxWidth: maxContentWidth,
      },
      messageImage: {
        ...baseStyles.messageImage,
        width: isWideScreen ? 280 : 220,
        height: isWideScreen ? 280 : 220,
      },
    });
  }, [maxContentWidth, isWideScreen, baseStyles]);

  // 系统通知消息特殊处理
  // 支持两种判断方式：
  // 1. is_system_notice 字段（WebSocket 推送时设置）
  // 2. category === 'notification'（从数据库加载时使用）
  // 3. sender_id === '10000'（系统发送者兜底）
  const isSystemNotice = message.is_system_notice || message.category === 'notification' || message.sender_id === '10000';
  
  const isMe = message.sender_id === currentUserId;
  const showTime = shouldShowTime(index);
  const isRecalled = message.status === 'recalled';
  const isRead = !isGroupChat && isMe && message.seq <= otherUserLastReadSeq;
  const isLastReadMessage = !isGroupChat && isMe && message.seq === otherUserLastReadSeq;
  
  // 检查是否有消息链（必须使用 segments 格式）
  // 安全检查：确保 segments 是数组
  const segments = Array.isArray(message.segments) ? message.segments : [];
  const hasSegments = segments.length > 0;
  // 检查是否是图片消息
  const isImage = Array.isArray(segments) && segments.some(s => s.type === 'image');
  // 纯图片：除 reply 外均为 image（支持多图同条）
  const segmentsWithoutReply = segments.filter(s => s.type !== 'reply');
  const isPureImageMessage =
    segmentsWithoutReply.length > 0 &&
    segmentsWithoutReply.every(s => s.type === 'image');
  
  // 提取所有图片 segments
  const imageSegments = segments
    .filter(s => s.type === 'image')
    .map((s, idx) => {
      const data = s.data as ImageSegmentData;
      return {
        id: `img-${message.id}-${idx}`,
        url: data.url || data.thumbnail_url || '',
        thumbnail_url: data.thumbnail_url,
        width: data.width,
        height: data.height,
      };
    });
  
  // 检查当前消息是否被选中
  
  // 获取发送者信息（群聊）- 供子组件使用
  const getSenderInfo = React.useCallback((senderId: string): SenderInfo => {
    if (senderId === currentUserId) {
      return {
        nickname: currentUser?.nickname || '我',
        avatar: currentUser?.avatar || null,
        userId: currentUserId,
      };
    }

    // 兜底：从群成员列表查找
    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?.nickname, currentUser?.avatar, groupMembers]);

  // 使用useMemo确保senderInfo在message.sender变化时重新计算
  const senderInfo = React.useMemo((): SenderInfo | null => {
    if (!isGroupChat) return null;

    const senderId = message.sender_id;

    if (senderId === currentUserId) {
      return {
        nickname: currentUser?.nickname || '我',
        avatar: currentUser?.avatar || null,
        userId: currentUserId,
      };
    }

    // 优先使用消息对象中携带的sender信息（MessageManager 已填充）
    if (message.sender && (message.sender.avatar || message.sender.nickname)) {
      return {
        nickname: message.sender.nickname || message.sender.username || '用户',
        avatar: message.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,
    };
  }, [isGroupChat, message.sender_id, message.sender, currentUserId, currentUser?.nickname, currentUser?.avatar, groupMembers]);
  
  // 创建成员映射（用于@高亮）
  const memberMap = useMemo(() => {
    const map = new Map<string, { nickname: string; user_id: string }>();
    groupMembers.forEach(m => {
      map.set(m.user_id, {
        nickname: m.nickname || m.user?.nickname || '用户',
        user_id: m.user_id,
      });
    });
    return map;
  }, [groupMembers]);

  // 记录按压位置
  const handlePressIn = (event: GestureResponderEvent) => {
    const { pageX, pageY } = event.nativeEvent;
    pressPositionRef.current = { x: pageX, y: pageY };
  };

  // 处理长按并获取位置
  const handleLongPress = () => {
    if (bubbleRef.current) {
      bubbleRef.current.measureInWindow((x, y, width, height) => {
        const position: MenuPosition = { 
          x, 
          y, 
          width, 
          height,
          pressX: pressPositionRef.current.x,
          pressY: pressPositionRef.current.y,
        };
        onLongPress(message, position);
      });
    } else {
      onLongPress(message);
    }
  };

  const renderBubbleShell = useCallback(
    (
      child: React.ReactNode,
      innerExtra: (object | undefined | null | false)[] = []
    ) => (
      <View
        style={[
          styles.messageBubbleOuter,
          isMe ? styles.myBubbleOuter : styles.theirBubbleOuter,
        ]}
      >
        <View
          style={[
            styles.messageBubbleInner,
            isMe ? styles.myBubbleInner : styles.theirBubbleInner,
            ...innerExtra.filter(Boolean),
          ]}
        >
          {child}
        </View>
      </View>
    ),
    [isMe, styles]
  );

  // 渲染消息内容
  const renderMessageContent = () => {
    // 撤回消息
    if (isRecalled) {
      return renderBubbleShell(
        <Text
          style={[
            isMe ? styles.myBubbleText : styles.theirBubbleText,
            styles.recalledText,
          ]}
          selectable={false}
        >
          消息已撤回
        </Text>,
        [styles.recalledBubble]
      );
    }

    // 使用消息链渲染（必须使用 segments 格式）
    // 从 segments 中获取被回复消息的 ID 和 seq，然后从 messageMap 中查找
    const getReplyMessage = (): GroupMessage | undefined => {
      const replySegment = segments.find(s => s.type === 'reply');
      if (replySegment && messageMap) {
        const replyData = replySegment.data as { id: string; seq?: number };
        const replyId = String(replyData.id);
        
        // 首先尝试通过 ID 查找
        let found = messageMap.get(replyId);
        
        // 如果通过 ID 找不到，尝试通过 seq 查找
        if (!found && replyData.seq !== undefined) {
          found = Array.from(messageMap.values()).find(msg => msg.seq === replyData.seq);
        }
        
        return found;
      }
      return undefined;
    };
    
    // 如果没有 segments，显示空内容或错误提示
    if (!hasSegments) {
      return renderBubbleShell(
        <Text
          style={[
            isMe ? styles.myBubbleText : styles.theirBubbleText,
            { opacity: 0.5 },
          ]}
          selectable={false}
        >
          [消息格式错误]
        </Text>
      );
    }
    
    // 检查是否有回复，用于调整气泡样式
    const hasReply = segments.some(s => s.type === 'reply');

    return renderBubbleShell(
      <MessageSegmentsRenderer
        segments={segments}
        isMe={isMe}
        currentUserId={currentUserId}
        memberMap={memberMap}
        replyMessage={getReplyMessage()}
        getSenderInfo={getSenderInfo}
        onAtPress={() => undefined}
        onReplyPress={onReplyPress}
        onImagePress={(url) => {
          // 查找点击的图片索引
          const clickIndex = imageSegments.findIndex(
            img => img.url === url || img.thumbnail_url === url
          );
          if (clickIndex !== -1 && onImagePress) {
            onImagePress(imageSegments, clickIndex);
          }
        }}
        onImageLongPress={(position?: { x: number; y: number }) => {
          // 图片长按触发和消息气泡一样的菜单
          // 如果有位置信息，直接使用；否则使用气泡位置
          if (position) {
            onLongPress(message, {
              x: 0,
              y: 0,
              width: 0,
              height: 0,
              pressX: position.x,
              pressY: position.y,
            });
          } else {
            handleLongPress();
          }
        }}
        onLinkPress={() => undefined}
      />,
      [hasReply && segmentStyles.replyBubble, isPureImageMessage && segmentStyles.pureImageBubble]
    );
  };

  // 处理滑动回复
  const handleSwipeReply = useCallback(() => {
    if (onReply) {
      onReply(message);
    }
  }, [onReply, message]);

  // 系统通知消息渲染
  if (isSystemNotice) {
    return (
      <View>
        {showTime && (
          <View style={styles.timeContainer}>
            <Text style={styles.timeText}>
              {formatTime(message.created_at)}
            </Text>
          </View>
        )}
        <View style={styles.systemNoticeContainer}>
          <Text style={styles.systemNoticeText}>{message.notice_content || extractTextFromSegments(message.segments)}</Text>
        </View>
      </View>
    );
  }

  // 消息内容渲染
  const messageContent = (
    <TouchableOpacity
      onPressIn={handlePressIn}
      onLongPress={handleLongPress}
      activeOpacity={1}
    >
      <View ref={bubbleRef}>
        {showTime && (
          <View style={styles.timeContainer}>
            <Text style={styles.timeText}>
              {formatTime(message.created_at)}
            </Text>
          </View>
        )}
        
        <View style={[styles.messageRow, isMe ? styles.myMessageRow : styles.theirMessageRow]}>
          {/* 群聊模式：显示发送者头像和昵称 */}
          {isGroupChat && !isMe && senderInfo && (
            <TouchableOpacity
              style={styles.groupAvatarWrapper}
              onPress={() => senderInfo?.userId && onAvatarPress(senderInfo.userId)}
              onLongPress={() => onAvatarLongPress(message.sender_id, senderInfo.nickname)}
              delayLongPress={500}
            >
              <Avatar
                source={senderInfo.avatar}
                size={40}
                name={senderInfo.nickname}
              />
            </TouchableOpacity>
          )}
          
          {/* 私聊模式：显示对方头像 */}
          {!isGroupChat && !isMe && (
            <TouchableOpacity
              style={styles.avatarWrapper}
              onPress={() => otherUser?.id && onAvatarPress(String(otherUser.id))}
            >
              <Avatar
                source={otherUser?.avatar || null}
                size={40}
                name={otherUser?.nickname || ''}
              />
            </TouchableOpacity>
          )}
          
          <View style={[styles.messageContent, isMe ? styles.myMessageContentPanel : null]}>
            {/* 群聊模式：显示发送者昵称 */}
            {isGroupChat && !isMe && senderInfo && (
              <Text style={styles.senderName}>{senderInfo.nickname}</Text>
            )}
            
            {renderMessageContent()}
            
            {/* 私聊模式：显示已读标记 */}
            {isLastReadMessage && (
              <View style={styles.readStatusContainer}>
                <MaterialCommunityIcons
                  name="check-all"
                  size={14}
                  color="#34C759"
                />
                <Text style={[styles.readStatusText, styles.readStatusTextRead]}>
                  已读
                </Text>
              </View>
            )}
          </View>
          
          {/* 自己的头像 */}
          {isMe && (
            <View style={styles.avatarWrapper}>
              <Avatar
                source={currentUser?.avatar || null}
                size={40}
                name={currentUser?.nickname || ''}
              />
            </View>
          )}
        </View>
      </View>
    </TouchableOpacity>
  );

  // 使用 SwipeableMessageBubble 包裹消息内容
  return (
    <SwipeableMessageBubble
      isMe={isMe}
      onReply={handleSwipeReply}
      enabled={!!onReply}
    >
      {messageContent}
    </SwipeableMessageBubble>
  );
};

// Segment 消息的特殊样式 - 自适应宽度
const segmentStyles = StyleSheet.create({
  replyBubble: {
    // 有回复消息时，使用自适应宽度
    minWidth: 120,
  },
  pureImageBubble: {
    // 纯图片消息：去除内边距，让图片紧贴气泡边缘
    paddingHorizontal: 0,
    paddingVertical: 0,
    overflow: 'hidden',
  },
});

export default MessageBubble;
