// 消息页面逻辑 - 基于Flutter实现
const app = getApp();
const apiClient = require('../../utils/api-client.js');
const wsManager = require('../../utils/websocket-manager-v2.js');
const chatAPI = require('../../utils/chat-api.js');
// 移除未使用的 friendAPI 依赖，避免无意义的打包与阅读负担
const { initPageSystemInfo } = require('../../utils/system-info-modern.js');

Page({
  data: {
    searchKeyword: '',
    refreshing: false,
    loading: false,
    
    // 会话数据
    conversations: [],
    pinnedConversations: [],
    normalConversations: [],
    totalUnreadCount: 0,
    
    // 过滤后的数据
    filteredConversations: [],
    
    // WebSocket状态
    wsConnected: false,
    
    // 系统适配信息
    systemInfo: {},
    statusBarHeight: 0,
    menuButtonHeight: 0,
    menuButtonTop: 0,
    navBarHeight: 0,
    windowHeight: 0,
    safeAreaBottom: 0,
    showSearch: false, // 新增：控制搜索栏的显示/隐藏
  themeClass: 'theme-dark',
  isThemeTransitioning: false,
  // 主题切换径向遮罩
  showThemeOverlay: false,
  overlayPlaying: false,
  overlayTo: 'theme-light',
  overlayX: 0,
  overlayY: 0,
  overlayDiameter: 0,
  overlayLeft: 0,
    overlayTop: 0,
    // 本地模糊搜索增强：抽样最近消息文本
    searching: false,
    conversationSamples: {}, // { [conversationId]: string[] }
    sampleLoading: {},       // { [conversationId]: boolean }
    lastSearchKeyword: ''
  },

  // 统一时间戳规范化：支持 number/纯数字字符串/ISO 字符串
  normalizeTimestamp(ts) {
    if (!ts && ts !== 0) return 0;
    if (typeof ts === 'number' && isFinite(ts)) return ts;
    if (typeof ts === 'string') {
      const s = ts.trim();
      if (!s) return 0;
      // 纯数字（可能是秒/毫秒）
      if (/^\d+$/.test(s)) {
        const n = parseInt(s, 10);
        // 假定 10 位为秒，13 位为毫秒
        return s.length === 10 ? n * 1000 : n;
      }
      // ISO 或其他可被 Date 解析的格式
      const d = Date.parse(s);
      return isNaN(d) ? 0 : d;
    }
    // 其他类型直接尝试 Date
    try {
      const d = new Date(ts).getTime();
      return isNaN(d) ? 0 : d;
    } catch (_) {
      return 0;
    }
  },

  // 页面加载
  onLoad: function (options) {
    console.log('消息页面加载');
    this.initSystemInfo();
    this.checkAuthAndInit();
    
    // 🔥 动态设置导航栏标题
    wx.setNavigationBarTitle({
      title: '消息'
    });
  },

  // 检查认证状态并初始化
  async checkAuthAndInit() {
    try {
      console.log('🔍 开始检查用户认证状态...');

      // 检查多种token来源
      const userInfo = wx.getStorageSync('userInfo');
      const directToken = wx.getStorageSync('token');
      const apiToken = apiClient.getToken();

      console.log('🔍 Token检查结果:', {
        hasUserInfo: !!userInfo,
        hasUserInfoToken: !!(userInfo?.token),
        hasDirectToken: !!directToken,
        hasApiToken: !!apiToken,
        userInfoTokenLength: userInfo?.token?.length || 0,
        directTokenLength: directToken?.length || 0,
        apiTokenLength: apiToken?.length || 0
      });

      // 确保API客户端能获取到token
      const currentToken = apiToken || userInfo?.token || directToken;

      if (!currentToken) {
        console.error('❌ 用户未登录，准备跳转到登录页');
        this.redirectToLogin('checkAuthAndInit');
        return;
      }

      console.log('✅ 消息页面认证检查通过，开始初始化');

      // 确保API客户端有token
      if (!apiToken && currentToken) {
        apiClient.setToken(currentToken);
        console.log('🔑 已设置API客户端token');
      }

      // 初始化WebSocket和加载数据
      this.initWebSocket();
      this.loadConversations();

    } catch (error) {
      console.error('❌ 消息页面认证检查失败:', error);
      this.redirectToLogin('exception');
    }
  },

  // 🔥 统一的登录页跳转方法 - 使用退出登录的成功模式
  redirectToLogin(source) {
    // 防止重复跳转
    if (this.redirecting) {
      console.log(`⚠️ 正在跳转中，忽略来自${source}的跳转请求`);
      return;
    }

    this.redirecting = true;
    console.log(`🔄 来自${source}的跳转请求，执行跳转...`);

    // 🔥 使用退出登录的成功模式：固定1000ms延迟 + 简单的reLaunch
    setTimeout(() => {
      wx.reLaunch({
        url: '/pages/login/login',
        success: () => {
          console.log('✅ 跳转到登录页成功');
          this.redirecting = false;
        },
        fail: (error) => {
          console.error('❌ 跳转到登录页失败:', error);
          this.redirecting = false;
        }
      });
    }, 1000); // 🔥 使用与退出登录相同的1000ms延迟
  },

  // 初始化系统信息
  initSystemInfo() {
    const pageSystemInfo = initPageSystemInfo();
    
    console.log('消息页面系统适配信息:', {
      statusBarHeight: pageSystemInfo.statusBarHeight,
      menuButtonHeight: pageSystemInfo.menuButtonHeight,
      menuButtonTop: pageSystemInfo.menuButtonTop,
      navBarHeight: pageSystemInfo.navBarHeight,
      windowHeight: pageSystemInfo.windowHeight,
      safeAreaBottom: pageSystemInfo.safeAreaBottom
    });
    
    this.setData({
      systemInfo: pageSystemInfo.systemInfo,
      statusBarHeight: pageSystemInfo.statusBarHeight,
      menuButtonHeight: pageSystemInfo.menuButtonHeight,
      menuButtonTop: pageSystemInfo.menuButtonTop,
      navBarHeight: pageSystemInfo.navBarHeight,
      windowHeight: pageSystemInfo.windowHeight,
      safeAreaBottom: pageSystemInfo.safeAreaBottom
    });
  },

  // 初始化WebSocket连接
  initWebSocket() {
    try {
      console.log('初始化WebSocket连接');
      
      // 获取用户token - 使用更可靠的方式
      let userInfo = app.globalData.userInfo;
      let token = null;
      
      if (userInfo && userInfo.token) {
        token = userInfo.token;
      } else {
        // 尝试从本地存储获取
        try {
          const storedUserInfo = wx.getStorageSync('userInfo');
          if (storedUserInfo && storedUserInfo.token) {
            token = storedUserInfo.token;
            userInfo = storedUserInfo;
            // 更新全局数据
            app.globalData.userInfo = userInfo;
            app.globalData.isLoggedIn = true;
          }
        } catch (error) {
          console.error('从本地存储获取用户信息失败:', error);
        }
      }
      
      if (!token) {
        console.error('WebSocket连接失败: 缺少认证token');
        // 不直接return，而是设置一个延迟重试
        setTimeout(() => {
          this.initWebSocket();
        }, 2000);
        return;
      }

      // 设置token并连接
      wsManager.setToken(token);
      
      // 注册消息处理器
      wsManager.on('new_message', (message) => {
        console.log('收到新消息:', message);
        this.handleNewMessage(message.data);
      });

      wsManager.on('conversation_update', (message) => {
        console.log('会话更新:', message);
        this.handleConversationUpdate(message.data);
      });

      wsManager.on('friend_request', (message) => {
        console.log('收到好友请求:', message);
        this.handleFriendRequest(message.data);
      });

      wsManager.on('global_connected', () => {
        console.log('WebSocket连接成功');
        this.setData({ wsConnected: true });
      });

      wsManager.on('global_disconnected', () => {
        console.log('WebSocket连接断开');
        this.setData({ wsConnected: false });
      });

      // 🔥 注册聊天功能处理器
      wsManager.onChatMessage((message) => {
        console.log('🔥 收到新聊天消息:', message);
        this.handleNewMessage(message.data);
      });

      wsManager.onUnreadCountUpdate((message) => {
        console.log('🔥 未读数更新:', message);
        this.updateUnreadCount(message.data);
      });

      // 🔥 注册好友功能处理器
      wsManager.onNotification((message) => {
        console.log('🔥 收到通知:', message);
        this.handleNotification(message.data);
      });

      wsManager.onFriendRequest((message) => {
        console.log('🔥 收到好友请求:', message);
        this.handleFriendRequest(message.data);
      });

      // 🔥 注册在线状态事件（presence）
      const handleOnline = (msg) => {
        console.log('👤 用户上线:', msg);
        this.updatePresenceStatus(msg?.data || msg, true);
      };
      const handleOffline = (msg) => {
        console.log('👤 用户离线:', msg);
        this.updatePresenceStatus(msg?.data || msg, false);
      };
      const handlePresence = (msg) => {
        const data = msg?.data || msg;
        const online = typeof data?.online === 'boolean' ? data.online : undefined;
        console.log('👤 在线状态更新:', data);
        if (online !== undefined) {
          this.updatePresenceStatus(data, online);
        }
      };
      this._presenceHandlers = { handleOnline, handleOffline, handlePresence };
      wsManager.on('user_online', handleOnline);
      wsManager.on('user_offline', handleOffline);
      wsManager.on('presence_update', handlePresence);

      // 开始连接
      wsManager.connect();
      
    } catch (error) {
      console.error('初始化WebSocket失败:', error);
    }
  },

  // 处理新消息
  handleNewMessage(messageData) {
    console.log('处理新消息:', messageData);

    // 保护：如果没有会话ID或消息为空，直接返回
    if (!messageData) return;

    // 复制列表以防直接修改原数组
    const conversations = Array.isArray(this.data.conversations) ? [...this.data.conversations] : [];

    // 更健壮的匹配：支持 conversationId、id、targetId（或 senderId）等字段
    const incomingConvId = messageData.conversationId || messageData.conversation_id || messageData.id || '';
    const incomingTargetId = messageData.targetId || messageData.receiverId || messageData.to || messageData.senderId || '';

    let foundIndex = conversations.findIndex(conv => {
      return conv.conversationId === incomingConvId || conv.id === incomingConvId ||
             conv.targetId === incomingTargetId || conv.targetId === (messageData.senderId || messageData.from);
    });

  if (foundIndex >= 0) {
      // 更新现有会话
      const conv = conversations[foundIndex];
      const ts = Number(messageData.sendTime || Date.now());
      conversations[foundIndex] = {
        ...conv,
        lastMessage: this.getMessagePreview(messageData),
        lastMessageType: messageData.msgType || 'text',
        lastMessageTime: this.formatMessageTime(ts),
        lastMsgTime: ts,
        // 只有当消息不是自己发出的情况下才增加未读
        unreadCount: (conv.unreadCount || 0) + ((messageData.senderId && (messageData.senderId !== (this.data.userInfo?.user?.customId || ''))) ? 1 : 0)
      };
      console.log('更新会话（index=' + foundIndex + '）未读数为:', conversations[foundIndex].unreadCount);
    } else {
      // 未找到会话：创建一个最小化的会话记录并插入到列表顶部
      const newConvId = incomingConvId || `conv_${Date.now()}`;
      const senderName = messageData.senderName || messageData.fromName || '陌生人';
      const ts = Number(messageData.sendTime || Date.now());
      const newConversation = {
        id: newConvId,
        conversationId: newConvId,
        type: messageData.chatType || 0,
        name: senderName,
        avatar: messageData.senderAvatar || '',
        isOnline: false,
        isPinned: false,
        isMuted: false,
        unreadCount: 1,
        lastMessage: this.getMessagePreview(messageData),
        lastMessageType: messageData.msgType || 'text',
        lastMessageTime: this.formatMessageTime(ts),
        lastMsgTime: ts,
        messageStatus: 'received',
        targetId: incomingTargetId || messageData.senderId || ''
      };

      conversations.unshift(newConversation);
      console.log('新增会话以显示未读提示:', newConversation);
    }

    // 写回并统一处理排序/角标等
    this.setData({ conversations });
    this.processConversations(conversations);

    // 播放提示音
    this.playMessageSound();

    // 更新tab角标（processConversations 内也会调用，但这里保证即时性）
    this.updateTabBadge();
  },

  // 获取消息预览
  getMessagePreview(message) {
    switch (message.msgType) {
      case 'text':
        return message.content || '[文本消息]';
      case 'image':
        return '[图片]';
      case 'audio':
        return '[语音]';
      case 'video':
        return '[视频]';
      case 'file':
        return '[文件]';
      case 'location':
        return '[位置]';
      default:
        return '[消息]';
    }
  },

  // 处理会话更新
  handleConversationUpdate(updateData) {
    console.log('会话更新:', updateData);
    // 重新加载会话列表
    this.loadConversations();
  },

  // 处理好友请求（精简：保留一个实现）
  handleFriendRequest(requestData) {
    console.log('收到好友请求:', requestData);
    wx.showToast({ title: '收到新的好友请求', icon: 'none', duration: 2000 });
  },

  // 页面显示
  onShow: function () {
    console.log('消息页面显示');

    // 初始化主题
    const savedTheme = wx.getStorageSync('theme') || 'theme-dark';
    this.setData({ themeClass: savedTheme });

    // 🔥 在刷新前检查登录状态
    const currentToken = apiClient.getToken();
    if (!currentToken) {
      console.warn('⚠️ onShow检测到用户未登录，跳转到登录页');
      this.redirectToLogin('onShow');
      return;
    }

    this.refreshConversations();
    // 启动定时刷新
    if (this._refreshTimer) clearInterval(this._refreshTimer);
    this._refreshTimer = setInterval(() => {
      console.log('定时刷新会话列表...');
      this.loadConversations();
    }, 10000); // 每10秒刷新一次
  },

  // 页面隐藏
  onHide: function () {
    console.log('消息页面隐藏');
    if (this._refreshTimer) {
      clearInterval(this._refreshTimer);
      this._refreshTimer = null;
    }
  },

  // 页面卸载
  onUnload: function () {
    console.log('消息页面卸载');
    if (this._refreshTimer) {
      clearInterval(this._refreshTimer);
      this._refreshTimer = null;
    }
    
    // 移除WebSocket监听器
    wsManager.off('new_message');
    wsManager.off('conversation_update');
    wsManager.off('friend_request');
    wsManager.off('global_connected');
    wsManager.off('global_disconnected');
    if (this._presenceHandlers) {
      wsManager.off('user_online', this._presenceHandlers.handleOnline);
      wsManager.off('user_offline', this._presenceHandlers.handleOffline);
      wsManager.off('presence_update', this._presenceHandlers.handlePresence);
      this._presenceHandlers = null;
    }
  },

  // 🔥 在线状态更新：根据 userId/targetId 更新对应会话的 isOnline
  updatePresenceStatus(data, isOnline) {
    try {
      const userId = data?.userId || data?.targetId || data?.uid || data?.id || data?.customId;
      if (!userId) {
        console.warn('⚠️ presence 事件缺少用户ID:', data);
        return;
      }

      const conversations = (this.data.conversations || []).map(conv => {
        // 单聊：targetId 等于该用户；群聊忽略
        if ((conv.type === 'single' || conv.chatType === 0) && (conv.targetId == userId || String(conv.targetId) === String(userId))) {
          return { ...conv, isOnline: !!isOnline };
        }
        return conv;
      });

      // 仅当有变化时写回
      const changed = JSON.stringify(conversations) !== JSON.stringify(this.data.conversations || []);
      if (changed) {
        this.setData({ conversations });
        this.processConversations(conversations);
      }
    } catch (err) {
      console.error('❌ 更新在线状态失败:', err);
    }
  },

  // 加载会话列表
  async loadConversations() {
    if (this.data.loading) return;

    // 🔥 在加载前检查登录状态
    const currentToken = apiClient.getToken();
    if (!currentToken) {
      console.warn('⚠️ loadConversations检测到用户未登录，停止加载');
      return;
    }

    try {
      this.setData({ loading: true });

      console.log('🔥 开始加载会话列表');
      const response = await chatAPI.getConversations();
      
      console.log('会话列表API响应:', response);
      
      if (response && response.code === 0) {
        const conversations = response.data || [];
        console.log('处理会话数据:', conversations);
        
        // 🔥 处理会话数据格式，过滤掉无效会话
        const processedConversations = conversations
          .map(conv => this.processConversationData(conv))
          .filter(conv => conv !== null); // 过滤掉null值
          
        console.log('处理后的会话数量:', processedConversations.length);
        this.processConversations(processedConversations);
      } else {
        throw new Error(response?.message || '获取会话列表失败');
      }
    } catch (error) {
      console.error('加载会话失败:', error);
      wx.showToast({
        title: '加载失败',
        icon: 'none'
      });
    } finally {
      this.setData({ loading: false });
    }
  },

  // 处理会话数据格式
  processConversationData(conv) {
    // 🔥 完全使用后端返回的会话ID，不再前端生成
    const conversationId = conv.id || conv.conversationId;
    
    if (!conversationId) {
      console.error('会话缺少ID，跳过该会话:', conv);
      return null; // 如果没有会话ID，跳过该会话
    }
    
    console.log('使用后端会话ID:', conversationId);
    
  // 统一提取原始时间戳
    const candidates = [conv.lastMsgTime, conv.lastMessageTimeTs, conv.updatedAt, conv.lastActiveAt];
    let rawTs = 0;
    for (const c of candidates) {
      const v = this.normalizeTimestamp(c);
      if (v) { rawTs = v; break; }
    }
    return {
      id: conversationId,
      conversationId: conversationId,
      type: conv.type === 1 ? 'group' : 'single', // 使用正确的type字段
      name: conv.targetName || conv.name || '未知',
      avatar: conv.targetAvatar || '',
      isOnline: conv.isOnline || false,
      isPinned: conv.isTop || false,
      isMuted: conv.isMuted || false,
      unreadCount: conv.unreadCount || 0,
      lastMessage: conv.lastMsgContent || conv.lastMessage || '',
      lastMessageType: conv.lastMsgType || 'text',
      lastMessageTime: this.formatMessageTime(rawTs),
      lastMsgTime: rawTs,
      messageStatus: conv.messageStatus || 'sent',
      targetId: conv.targetId || conv.userId || '',
      chatType: conv.type || conv.chatType || 0 // 使用正确的type字段
    };
  },

  // 格式化消息时间（Telegram 风格）
  formatMessageTime(timestamp) {
    if (!timestamp) return '';
    const now = new Date();
    const msg = new Date(timestamp);

    // 今天：HH:mm
    if (now.toDateString() === msg.toDateString()) {
      const hh = msg.getHours().toString().padStart(2, '0');
      const mm = msg.getMinutes().toString().padStart(2, '0');
      return `${hh}:${mm}`;
    }

    // 昨天
    const y = new Date(now);
    y.setDate(y.getDate() - 1);
    if (y.toDateString() === msg.toDateString()) {
      return '昨天';
    }

    // 更早：YYYY/MM/DD
    const year = msg.getFullYear();
    const month = (msg.getMonth() + 1).toString().padStart(2, '0');
    const day = msg.getDate().toString().padStart(2, '0');
    return `${year}/${month}/${day}`;
  },

  // 播放消息提示音
  playMessageSound() {
    try {
      // 简单的提示，小程序没有播放背景音频的能力
      wx.vibrateShort();
    } catch (error) {
      console.log('提示异常:', error);
    }
  },

  // 更新Tab角标
  updateTabBadge() {
    const totalUnread = this.data.totalUnreadCount;
    if (totalUnread > 0) {
      wx.setTabBarBadge({
        index: 1, // 消息tab的索引
        text: totalUnread > 99 ? '99+' : totalUnread.toString()
      });
    } else {
      wx.removeTabBarBadge({
        index: 1
      });
    }
  },

  // 处理会话数据
  processConversations(conversations) {
    // 过滤已删除项，并统一关键字段
  const validList = (conversations || [])
      .filter(it => it && !it.deleted && !it._deleted)
      .map(it => ({
        ...it,
        // 统一置顶字段（isTop 与 isPinned 兼容）
        isPinned: !!(it.isPinned || it.isTop),
        // 统一时间字段用于排序（降序）
    _ts: this.normalizeTimestamp(it.lastMsgTime || it.lastMessageTimeTs || it.lastActiveAt || it.updatedAt)
      }));

    // 置顶/非置顶分组并组内按时间降序
    const pinnedConversations = validList
      .filter(item => item.isPinned)
      .sort((a, b) => b._ts - a._ts);
    const normalConversations = validList
      .filter(item => !item.isPinned)
      .sort((a, b) => b._ts - a._ts);

    const sortedAll = [...pinnedConversations, ...normalConversations];
    const totalUnreadCount = validList.reduce((sum, item) => sum + (item.unreadCount || 0), 0);

    this.setData({
      conversations: sortedAll,
      pinnedConversations,
      normalConversations,
      totalUnreadCount,
      filteredConversations: sortedAll
    });

    // 更新角标
    this.updateTabBadge();
  },

  // 刷新会话列表
  async refreshConversations() {
    this.setData({ refreshing: true });
    await this.loadConversations();
    this.setData({ refreshing: false });
  },

  // 下拉刷新
  onRefresh() {
    this.refreshConversations();
  },

  // 搜索输入
  onSearchInput(e) {
    const keyword = (e.detail.value || '').trim();
    this.setData({ searchKeyword: keyword, lastSearchKeyword: keyword, searching: !!keyword });
    if (!keyword) {
      this.setData({ searching: false });
      this.processConversations(this.data.conversations);
      return;
    }
    // 立即本地模糊过滤
    this.fuzzyFilterConversations(keyword);
    // 异步预取若干可能相关会话的最近消息样本
    this.prefetchTopConversationSamples(keyword);
  },

  // 清除搜索
  clearSearch() {
    this.setData({ searchKeyword: '', lastSearchKeyword: '', searching: false });
    this.processConversations(this.data.conversations);
  },

  // 显示/隐藏搜索栏
  showSearchBar() { this.setData({ showSearch: true }); },
  hideSearchBar() { this.setData({ showSearch: false, searchKeyword: '', lastSearchKeyword: '', searching: false }); this.processConversations(this.data.conversations); },

  // 本地模糊过滤：名称/最后一条消息/抽样最近消息（文本）
  fuzzyFilterConversations(keyword) {
    if (!keyword) {
      this.processConversations(this.data.conversations);
      return;
    }

    const q = (keyword || '').toLowerCase();

    const subseqScore = (text, query) => {
      if (!text || !query) return 0;
      const s = String(text).toLowerCase();
      let pos = 0, score = 0, streak = 0;
      for (const ch of query) {
        const idx = s.indexOf(ch, pos);
        if (idx === -1) return score;
        score += 1;
        streak = (idx === pos) ? streak + 1 : 1;
        score += Math.min(streak, 3) * 0.5;
        pos = idx + 1;
      }
      if (s.startsWith(query)) score += 2;
      if (s.includes(query)) score += 1;
      return score;
    };

    const samples = this.data.conversationSamples || {};
    const list = this.data.conversations || [];

    const withScore = list.map(item => {
      const nameScore = subseqScore(item.name || '', q);
      const lastScore = subseqScore(item.lastMessage || '', q);
      const sampleTexts = samples[item.conversationId] || [];
      let sampleScore = 0;
      for (const t of sampleTexts) sampleScore = Math.max(sampleScore, subseqScore(t, q));
      const score = nameScore * 2 + Math.max(sampleScore * 1.5, lastScore);
      return { item, score };
    }).filter(x => x.score > 0);

    withScore.sort((a, b) => {
      if (b.score !== a.score) return b.score - a.score;
      const at = this.normalizeTimestamp(a.item.lastMsgTime || a.item.lastMessageTimeTs);
      const bt = this.normalizeTimestamp(b.item.lastMsgTime || b.item.lastMessageTimeTs);
      return bt - at;
    });

    let filtered = withScore.map(x => x.item);
    if (filtered.length === 0) {
      // 兜底：简单包含匹配
      filtered = list.filter(item => {
        const name = String(item.name || '').toLowerCase();
        const msg = String(item.lastMessage || '').toLowerCase();
        return name.includes(q) || msg.includes(q);
      });
    }

    const pinnedFiltered = filtered.filter(i => i.isPinned);
    const normalFiltered = filtered.filter(i => !i.isPinned);

    this.setData({
      pinnedConversations: pinnedFiltered,
      normalConversations: normalFiltered,
      filteredConversations: filtered
    });
  },

  // 预取：对可能相关的会话抓取最近消息文本样本
  async prefetchTopConversationSamples(keyword) {
    const q = (keyword || '').toLowerCase();
    const list = this.data.conversations || [];
    // 粗筛：名称/最后消息包含命中的，取前8
    const rough = list
      .map(item => ({ item, s: (String(item.name||'').toLowerCase().includes(q)?2:0) + (String(item.lastMessage||'').toLowerCase().includes(q)?1:0) }))
      .sort((a,b)=>b.s-a.s)
      .slice(0,8)
      .map(x=>x.item);

    const tasks = [];
    for (const conv of rough) {
      const cid = conv.conversationId;
      if (!cid) continue;
      if ((this.data.conversationSamples||{})[cid]) continue;
      if ((this.data.sampleLoading||{})[cid]) continue;
      tasks.push(this.fetchConversationSample(conv));
      if (tasks.length >= 4) break; // 控制并发与数量
    }

    if (tasks.length) {
      await Promise.allSettled(tasks);
      // 关键词未变化时刷新一次
      if ((this.data.lastSearchKeyword||'') === (keyword||'')) {
        this.fuzzyFilterConversations(keyword);
      }
    }
  },

  async fetchConversationSample(conv) {
    const cid = conv.conversationId;
    try {
      const loading = { ...(this.data.sampleLoading||{}) };
      loading[cid] = true;
      this.setData({ sampleLoading: loading });

      const params = {
        receiverId: conv.targetId,
        chatType: conv.chatType !== undefined ? conv.chatType : (conv.type === 'group' ? 1 : 0),
        limit: 20,
        direction: 'before'
      };
      const resp = await apiClient.get('/api/v1/chat/history', params);
      let texts = [];
      if (resp && (resp.code === 0 || resp.code === 200)) {
        const arr = Array.isArray(resp.data) ? resp.data : (Array.isArray(resp.data?.list) ? resp.data.list : []);
        texts = arr
          .map(m => {
            const c = (typeof m?.content === 'string' && m.content) ? m.content
              : (typeof m?.text === 'string' ? m.text : (typeof m?.summary === 'string' ? m.summary : ''));
            return c;
          })
          .filter(s => typeof s === 'string' && s.trim())
          .slice(0, 20);
      }

      const samples = { ...(this.data.conversationSamples||{}) };
      samples[cid] = texts;
      const loadingDone = { ...(this.data.sampleLoading||{}) };
      delete loadingDone[cid];
      this.setData({ conversationSamples: samples, sampleLoading: loadingDone });
    } catch (e) {
      const loadingDone = { ...(this.data.sampleLoading||{}) };
      delete loadingDone[cid];
      this.setData({ sampleLoading: loadingDone });
    }
  },

  // 移除旧版 filterConversations；已被 fuzzyFilterConversations 取代

  // 打开聊天
  openChat(e) {
    const conversation = e.currentTarget.dataset.conversation;
    console.log('打开聊天:', conversation);

    // 检查必要参数
    if (!conversation.targetId) {
      console.error('缺少targetId，无法打开聊天');
      wx.showToast({
        title: '聊天信息错误',
        icon: 'none'
      });
      return;
    }

    // 标记为已读
    if (conversation.unreadCount > 0) {
      this.markConversationRead(conversation.conversationId);
    }

    // 🔥 确保chatType有默认值
    const chatType = conversation.chatType !== undefined ? conversation.chatType : 0;
    console.log('确定的chatType:', chatType, '原始值:', conversation.chatType);

    // 跳转到聊天页面
    const params = {
      conversationId: conversation.conversationId,
      targetId: conversation.targetId,
      name: encodeURIComponent(conversation.name),
      chatType: chatType
    };
    // 若当前存在搜索关键词，则作为锚点关键词传递，用于在聊天页内定位
    const kw = (this.data.searchKeyword || '').trim();
    if (kw) {
      params.keyword = encodeURIComponent(kw);
    }
    
    const queryString = Object.keys(params)
      .map(key => `${key}=${params[key]}`)
      .join('&');
    
    console.log('聊天页面参数:', params);
    
    wx.navigateTo({
      url: `/pages/message/chat/chat?${queryString}`
    });
  },

  // 显示会话选项
  showConversationOptions(e) {
    const conversation = e.currentTarget.dataset.conversation;
    
    const itemList = [
      (conversation.isPinned || conversation.isTop) ? '取消置顶' : '置顶会话',
      conversation.isMuted ? '取消免打扰' : '免打扰',
      '删除会话'
    ];

    wx.showActionSheet({
      itemList: itemList,
      success: (res) => {
        switch (res.tapIndex) {
          case 0:
            this.toggleConversationTop(conversation.conversationId);
            break;
          case 1:
            this.toggleConversationMute(conversation.conversationId);
            break;
          case 2:
            this.deleteConversation(conversation.conversationId);
            break;
        }
      }
    });
  },

  // 标记会话已读
  async markConversationRead(conversationId) {
    try {
      // TODO: 调用API标记已读
      await apiClient.markMessagesRead(conversationId);
      
      // 更新本地数据
      const conversations = this.data.conversations.map(conv => {
        if (conv.conversationId === conversationId) {
          return { ...conv, unreadCount: 0 };
        }
        return conv;
      });
      
      this.processConversations(conversations);
    } catch (error) {
      console.error('标记已读失败:', error);
    }
  },

  // 全部标记为已读
  markAllRead() {
    if (this._markingAll) return;
    const unreadIds = (this.data.conversations || [])
      .filter(c => (c.unreadCount || 0) > 0)
      .map(c => c.conversationId)
      .filter(Boolean);

    if (!unreadIds.length) {
      wx.showToast({ title: '暂无未读', icon: 'none' });
      return;
    }

    wx.showModal({
      title: '确认操作',
      content: '将所有会话标记为已读？',
      success: async (res) => {
        if (!res.confirm) return;
        this._markingAll = true;
        try {
          // 1) 立即本地清零，给用户即时反馈
          const conversations = (this.data.conversations || []).map(conv => ({
            ...conv,
            unreadCount: 0
          }));
          this.processConversations(conversations);
          wx.showToast({ title: '全部已读', icon: 'success' });

          // 2) 后台逐会话标记已读（并发执行）
          await Promise.allSettled(unreadIds.map(id => chatAPI.markAllRead(id)));

          // 3) 刷新总未读徽章（防止后端有残留）
          try {
            const resp = await chatAPI.getTotalUnreadCount();
            const total = (resp && (resp.code === 0 || resp.code === 200) && (resp.data?.total || resp.total)) ? (resp.data?.total || resp.total) : 0;
            this.setData({ totalUnreadCount: total });
            if (total > 0) {
              wx.setTabBarBadge({ index: 1, text: total > 99 ? '99+' : String(total) });
            } else {
              wx.removeTabBarBadge({ index: 1 });
            }
          } catch (_) { /* 忽略统计刷新失败 */ }
        } catch (error) {
          console.error('全部标记已读失败:', error);
          wx.showToast({ title: '操作失败', icon: 'none' });
        } finally {
          this._markingAll = false;
        }
      }
    });
  },

  // 发起聊天入口：统一打开顶部菜单（创建群聊/添加好友/扫一扫/设置）
  startNewChat() { this.showMenu(); },

  // 🔥 ===== 新增的聊天功能处理方法 =====

  // 更新未读数
  updateUnreadCount(data) {
    try {
      if (data.conversationId) {
        // 更新特定会话的未读数
        const conversations = this.data.conversations.map(conv => {
          if (conv.conversationId === data.conversationId) {
            return {
              ...conv,
              unreadCount: data.unreadCount || 0
            };
          }
          return conv;
        });

        this.setData({ conversations });
        this.processConversations(conversations);
      }

      if (data.totalUnreadCount !== undefined) {
        // 更新总未读数
        this.setData({ totalUnreadCount: data.totalUnreadCount });

        // 更新tabBar徽章
        if (data.totalUnreadCount > 0) {
          wx.setTabBarBadge({
            index: 1, // 消息tab的索引
            text: data.totalUnreadCount > 99 ? '99+' : data.totalUnreadCount.toString()
          });
        } else {
          wx.removeTabBarBadge({ index: 1 });
        }
      }
    } catch (error) {
      console.error('更新未读数失败:', error);
    }
  },

  // 处理通知
  handleNotification(data) {
    try {
      console.log('处理通知:', data);

      // 根据通知类型进行不同处理
      switch (data.type) {
        case 'new_friend_request':
          this.handleFriendRequestNotification(data);
          break;
        case 'friend_accepted':
          this.handleFriendAcceptedNotification(data);
          break;
        case 'friend_rejected':
          this.handleFriendRejectedNotification(data);
          break;
        default:
          console.log('未知通知类型:', data.type);
      }
    } catch (error) {
      console.error('处理通知失败:', error);
    }
  },

  // 移除重复的 handleFriendRequest 定义（上方已保留）

  // 处理好友请求通知
  handleFriendRequestNotification(data) {
    wx.showToast({
      title: `${data.senderName} 想和您成为好友`,
      icon: 'none',
      duration: 2000
    });
  },

  // 处理好友请求被接受通知
  handleFriendAcceptedNotification(data) {
    wx.showToast({
      title: `${data.senderName} 接受了您的好友请求`,
      icon: 'success',
      duration: 2000
    });
  },

  // 处理好友请求被拒绝通知
  handleFriendRejectedNotification(data) {
    wx.showToast({
      title: '好友请求被拒绝',
      icon: 'none',
      duration: 2000
    });
  },

  // 🔥 ===== 会话操作增强 =====

  // 置顶/取消置顶会话
  async toggleConversationTop(conversationId) {
    try {
      const conversation = this.data.conversations.find(conv => conv.conversationId === conversationId);
      if (!conversation) return;

      const newTopStatus = !conversation.isTop;

      await chatAPI.updateConversation(conversationId, {
        isTop: newTopStatus
      });

      // 更新本地数据
      const conversations = this.data.conversations.map(conv => {
        if (conv.conversationId === conversationId) {
          return { ...conv, isTop: newTopStatus };
        }
        return conv;
      });

      this.setData({ conversations });
      this.processConversations(conversations);

      wx.showToast({
        title: newTopStatus ? '已置顶' : '已取消置顶',
        icon: 'success'
      });

    } catch (error) {
      console.error('切换置顶状态失败:', error);
      wx.showToast({
        title: '操作失败',
        icon: 'none'
      });
    }
  },

  // 静音/取消静音会话
  async toggleConversationMute(conversationId) {
    try {
      const conversation = this.data.conversations.find(conv => conv.conversationId === conversationId);
      if (!conversation) return;

      const newMuteStatus = !conversation.isMuted;

      await chatAPI.updateConversation(conversationId, {
        isMuted: newMuteStatus
      });

      // 更新本地数据
      const conversations = this.data.conversations.map(conv => {
        if (conv.conversationId === conversationId) {
          return { ...conv, isMuted: newMuteStatus };
        }
        return conv;
      });

      this.setData({ conversations });
      this.processConversations(conversations);

      wx.showToast({
        title: newMuteStatus ? '已静音' : '已取消静音',
        icon: 'success'
      });

    } catch (error) {
      console.error('切换静音状态失败:', error);
      wx.showToast({
        title: '操作失败',
        icon: 'none'
      });
    }
  },

  // 删除会话
  async deleteConversation(conversationId) {
    try {
      await chatAPI.deleteConversation(conversationId);

      // 从本地数据中移除
      const conversations = this.data.conversations.filter(conv => conv.conversationId !== conversationId);

      this.setData({ conversations });
      this.processConversations(conversations);

      wx.showToast({
        title: '已删除',
        icon: 'success'
      });

    } catch (error) {
      console.error('删除会话失败:', error);
      wx.showToast({
        title: '删除失败',
        icon: 'none'
      });
    }
  },

  // 显示菜单
  showMenu() {
    console.log('📋 显示菜单');

    const itemList = ['创建群聊', '添加好友', '扫一扫', '设置'];

    wx.showActionSheet({
      itemList: itemList,
      success: (res) => {
        switch (res.tapIndex) {
          case 0:
            this.createGroup();
            break;
          case 1:
            this.addFriend();
            break;
          case 2:
            this.scanQRCode();
            break;
          case 3:
            this.openSettings();
            break;
          default:
            console.log('选择菜单项:', res.tapIndex);
        }
      }
    });
  },

  // 创建群聊
  createGroup() {
    console.log('👥 创建群聊');
    wx.navigateTo({
      url: '/pages/group/create-group/create-group'
    });
  },

  // 添加好友
  addFriend() {
    console.log('👤 添加好友');
    wx.navigateTo({
      url: '/pages/social/search/search'
    });
  },

  // 扫一扫
  scanQRCode() {
    console.log('📷 扫一扫');
    wx.scanCode({
      success: (res) => {
        console.log('扫码结果:', res);
        // 处理扫码结果
        this.handleScanResult(res);
      },
      fail: (error) => {
        console.error('❌ 扫码失败:', error);
        wx.showToast({
          title: '扫码失败',
          icon: 'none'
        });
      }
    });
  },

  // 处理扫码结果
  handleScanResult(result) {
    const { result: scanResult } = result;

    try {
      // 尝试解析为JSON
      const data = JSON.parse(scanResult);

      if (data.type === 'user') {
        // 用户二维码
        wx.navigateTo({
          url: `/pages/social/user-profile/user-profile?userId=${data.userId}`
        });
      } else if (data.type === 'group') {
        // 群聊二维码
        wx.showModal({
          title: '加入群聊',
          content: `确定要加入群聊"${data.groupName}"吗？`,
          success: (res) => {
            if (res.confirm) {
              this.joinGroupByQR(data.groupId);
            }
          }
        });
      } else {
        // 其他类型
        wx.showToast({
          title: '不支持的二维码类型',
          icon: 'none'
        });
      }
    } catch (error) {
      // 不是JSON格式，可能是URL或其他格式
      if (scanResult.startsWith('http')) {
        // 网址
        wx.showModal({
          title: '打开网址',
          content: scanResult,
          success: (res) => {
            if (res.confirm) {
              // 复制到剪贴板
              wx.setClipboardData({
                data: scanResult
              });
            }
          }
        });
      } else {
        // 其他文本
        wx.showModal({
          title: '扫码结果',
          content: scanResult,
          showCancel: false
        });
      }
    }
  },

  // 通过二维码加入群聊
  async joinGroupByQR(groupId) {
    try {
      wx.showLoading({
        title: '加入群聊中...'
      });

      const response = await apiClient.request({
        url: `/api/v1/groups/${groupId}/join`,
        method: 'POST'
      });

      wx.hideLoading();

      if (response.success) {
        wx.showToast({
          title: '加入群聊成功',
          icon: 'success'
        });

        // 刷新会话列表
        this.loadConversations();
      } else {
        wx.showToast({
          title: response.error || '加入群聊失败',
          icon: 'none'
        });
      }

    } catch (error) {
      wx.hideLoading();
      console.error('❌ 加入群聊失败:', error);
      wx.showToast({
        title: '加入群聊失败',
        icon: 'none'
      });
    }
  },

  // 打开设置
  openSettings() {
    console.log('⚙️ 打开设置');
    wx.navigateTo({
      url: '/pages/profile/profile'
    });
  },

  // 切换主题（带过渡动画）
  toggleTheme() {
    const next = this.data.themeClass === 'theme-dark' ? 'theme-light' : 'theme-dark';
    const query = wx.createSelectorQuery();
    query.select('.theme-toggle').boundingClientRect();
    query.selectViewport().boundingClientRect();
    query.exec((res) => {
      const btnRect = res && res[0];
      const vpRect = res && res[1];
  // 兜底：左上角区域，和按钮在左侧的位置一致
  let cx = 24;
  let cy = (this.data.statusBarHeight || 0) + 16;
      if (btnRect) {
        cx = btnRect.left + btnRect.width / 2;
        cy = btnRect.top + btnRect.height / 2;
      }
      const w = vpRect ? vpRect.width : (this.data.systemInfo?.windowWidth || 375);
      const h = vpRect ? vpRect.height : (this.data.systemInfo?.windowHeight || this.data.windowHeight || 667);
      const dx = Math.max(cx, w - cx);
      const dy = Math.max(cy, h - cy);
      const radius = Math.ceil(Math.sqrt(dx * dx + dy * dy)) + 12;
  const diameter = radius * 2;
  const left = Math.round(cx - radius);
  const top = Math.round(cy - radius);

      this.setData({
        isThemeTransitioning: true,
        showThemeOverlay: true,
        overlayPlaying: false,
        overlayTo: next,
        overlayX: cx,
        overlayY: cy,
  overlayDiameter: diameter,
  overlayLeft: left,
  overlayTop: top
      });
      setTimeout(() => {
        this.setData({ overlayPlaying: true, themeClass: next });
        try { wx.setStorageSync('theme', next); } catch (e) { console.warn('保存主题失败', e); }
      }, 16);
      setTimeout(() => {
        this.setData({ showThemeOverlay: false, overlayPlaying: false, isThemeTransitioning: false });
      }, 420);
    });
  }
});