// utils/chat-core.js — 全局 IM 连接、监听、重连、角标
import GoEasy from '../static/lib/goeasy-2.13.24.esm.min';
import { jianquanxian } from './imAuth/jianquanxian';
import { parseOrderCardText } from './group-chat.js';
import { persistGroupMeta, getFreshImUser, getImUserIdForRole, getLocalImUserId, getLocalImIdentity } from './im-user.js';

let _globalPrivateHandler = null;
let _globalGroupHandler = null;
let _globalConvHandler = null;
let _imLockDepth = 0;
let _loadConvTimer = null;
let _loadConvInFlight = false;

async function withImLock(fn) {
  if (_imLockDepth > 0) {
    return await fn();
  }
  _imLockDepth += 1;
  try {
    return await fn();
  } finally {
    _imLockDepth -= 1;
  }
}

function initGlobalMessageSystem(app) {
  app.updateUnreadCount = (count) => updateUnreadCount(app, count);
  app.disconnectGoEasy = () => disconnectGoEasy(app);
  app.ensureConnection = () => ensureConnection(app);
  app.connectWithIdentity = (identityType, userId, isAutoRestore) =>
    connectWithIdentity(app, identityType, userId, isAutoRestore);
  app.connectForCurrentRole = () => connectForCurrentRole(app);
  app.switchRoleAndReconnect = (newRole) => switchRoleAndReconnect(app, newRole);
  app.toggleDoNotDisturb = (enabled) => toggleDoNotDisturb(app, enabled);
  app.toggleNotificationMute = (enabled) => toggleNotificationMute(app, enabled);
  app.closeNotification = () => closeNotification(app);
  app.loadConversations = () => loadConversations(app);
  app.updateCurrentPageState = () => updateCurrentPageState(app);
  app.getSavedConnection = () => getSavedConnection(app);
  app.clearSavedConnection = () => clearSavedConnection(app);
  app.saveConnectionState = () => saveConnectionState(app);
  app.handleNewMessage = (message) => handleNewMessage(app, message);
  app.ensureImForRole = (role) => ensureImForRole(app, role);
  app.syncConnectionStatus = () => syncConnectionStatus(app);
  app.restoreTabBarBadge = () => restoreCachedBadge(app);
  app.startImWhenReady = () => startImWhenReady(app);

  loadUserSettings(app);
  initNetworkListener(app);
  initAppStateListener(app);
  bindGoEasyLifecycle(app);
  setupEventSystem(app);
  checkAndRestoreConnection(app);
}

function bindGoEasyLifecycle(app) {
  if (!wx.goEasy || app._goEasyLifecycleBound) return;
  app._goEasyLifecycleBound = true;
  try {
    wx.goEasy.on('connected', () => {
      app.globalData.goEasyConnection.status = 'connected';
      app.globalData.goEasyConnection.autoReconnect = true;
      setupMessageListeners(app);
      loadConversations(app);
      startHeartbeat(app);
      syncConnectionStatus(app);
    });
    wx.goEasy.on('disconnected', () => {
      app.globalData.goEasyConnection.status = 'disconnected';
      if (!app._imSuppressDisconnectEvent) {
        app.emitEvent('connectionChanged', { status: 'disconnected' });
      }
      if (app.globalData.goEasyConnection.autoReconnect) {
        setTimeout(() => ensureConnection(app), app.globalData.goEasyConnection.config.reconnectDelay);
      }
    });
  } catch (e) {
    console.warn('绑定 GoEasy 生命周期失败:', e);
  }
}

function getCurrentGoEasyUserId() {
  return (wx.goEasy && wx.goEasy.im && wx.goEasy.im.userId) || null;
}

function getExpectedImUserId(app) {
  const fromLocal = getLocalImUserId(app);
  if (fromLocal) return fromLocal;
  const uid = wx.getStorageSync('uid');
  if (!uid) return '';
  const role = app.globalData.currentRole || getLocalImIdentity(app) || 'normal';
  return getImUserIdForRole(role, uid);
}

function loadUserSettings(app) {
  try {
    const messageSettings = wx.getStorageSync(app.globalData.messageManager.cacheKeys.messageSettings);
    if (messageSettings) {
      app.globalData.messageManager = { ...app.globalData.messageManager, ...messageSettings };
    }
    const notificationMuted = wx.getStorageSync(app.globalData.messageManager.cacheKeys.notificationMuted);
    if (notificationMuted !== '') {
      app.globalData.messageManager.notificationMuted = notificationMuted;
    }
    const savedUnread = wx.getStorageSync(app.globalData.messageManager.cacheKeys.unreadTotal);
    if (savedUnread !== '' && savedUnread !== undefined) {
      app.globalData.messageManager.unreadTotal = savedUnread;
      updateTabBarBadge(app, savedUnread);
    }
    const savedMessages = wx.getStorageSync(app.globalData.messageManager.cacheKeys.latestMessages);
    if (savedMessages) {
      app.globalData.messageManager.latestMessages = savedMessages;
    }
  } catch (error) {
    console.warn('加载用户设置失败:', error);
  }
}

function initNetworkListener(app) {
  wx.onNetworkStatusChange((res) => {
    if (res.isConnected) {
      app.globalData.goEasyConnection.autoReconnect = true;
      app.globalData.goEasyConnection.reconnectAttempts = 0;
      app.emitEvent('connectionChanged', { status: 'reconnecting', reason: 'network' });
      ensureConnection(app);
    } else {
      app.globalData.goEasyConnection.status = 'disconnected';
      app.emitEvent('connectionChanged', { status: 'disconnected', reason: 'network' });
    }
  });
}

function initAppStateListener(app) {
  wx.onAppShow(() => {
    updateCurrentPageState(app);
    app.globalData.goEasyConnection.autoReconnect = true;
    restoreCachedBadge(app);
    ensureConnection(app);
    setTimeout(() => loadConversations(app), 400);
  });
  wx.onAppHide(() => {
    pauseHeartbeat(app);
    saveConnectionState(app);
  });
}

function checkAndRestoreConnection(app) {
  try {
    const savedConnection = wx.getStorageSync(app.globalData.goEasyConnection.cacheKeys.savedConnection);
    if (savedConnection && savedConnection.userId && savedConnection.identityType) {
      const now = Date.now();
      const lastTime = savedConnection.lastConnectTime || 0;
      const hoursDiff = (now - lastTime) / (1000 * 60 * 60);
      const validityHours = app.globalData.goEasyConnection.config.cacheValidityHours || 12;
      if (hoursDiff > validityHours) {
        clearSavedConnection(app);
      }
    }
    ensureConnection(app);
  } catch (error) {
    console.warn('检查保存的连接信息失败:', error);
  }
}

function setupEventSystem(app) {
  if (!app.globalData.eventListeners) {
    app.globalData.eventListeners = {};
  }
}

function isSdkConnected() {
  if (!wx.goEasy?.getConnectionStatus) return false;
  const s = wx.goEasy.getConnectionStatus();
  return s === 'connected' || s === 'reconnected';
}

function isImConnected() {
  return isSdkConnected();
}

/** 已连接且身份正确则直接恢复监听，避免重复 connect 触发 408 */
function adoptExistingConnection(app, identityType, userId) {
  app.globalData.goEasyConnection.status = 'connected';
  app.globalData.goEasyConnection.userId = userId;
  app.globalData.goEasyConnection.identityType = identityType;
  app.globalData.goEasyConnection.autoReconnect = true;
  app.globalData.goEasyConnection.reconnectAttempts = 0;
  saveConnectionState(app);
  startHeartbeat(app);
  setupMessageListeners(app);
  loadConversations(app);
  syncConnectionStatus(app);
}

/** 根据 SDK 真实状态同步 UI（避免已连接仍显示未连接） */
function syncConnectionStatus(app) {
  if (app.globalData.chatEnabled === false) {
    app.emitEvent('connectionChanged', { status: 'disabled', reason: 'chat_disabled' });
    return;
  }
  const expectedId = getExpectedImUserId(app);
  if (!expectedId) {
    app.emitEvent('connectionChanged', { status: 'disconnected', reason: 'no_uid' });
    return;
  }
  const cur = getCurrentGoEasyUserId();
  if (isSdkConnected() && (!cur || cur === expectedId)) {
    app.globalData.goEasyConnection.status = 'connected';
    app.globalData.goEasyConnection.userId = cur || expectedId;
    app.globalData.goEasyConnection.autoReconnect = true;
    setupMessageListeners(app);
    loadConversations(app);
    restoreCachedBadge(app);
    app.emitEvent('connectionChanged', { status: 'connected' });
    return;
  }
  const st = app.globalData.goEasyConnection.status;
  if (st === 'connecting' || st === 'reconnecting') {
    app.emitEvent('connectionChanged', { status: st });
  } else {
    app.emitEvent('connectionChanged', { status: 'disconnected' });
  }
}

function ensureConnection(app) {
  if (!wx.goEasy?.connect) return;
  if (app.globalData.chatEnabled === false) {
    syncConnectionStatus(app);
    return;
  }

  const expectedId = getExpectedImUserId(app);
  if (!expectedId) return;

  const role = app.globalData.currentRole || 'normal';

  if (isImConnected()) {
    const cur = getCurrentGoEasyUserId();
    if (cur === expectedId) {
      setupMessageListeners(app);
      startHeartbeat(app);
      loadConversations(app);
      syncConnectionStatus(app);
      return;
    }
    connectForCurrentRole(app);
    return;
  }

  app.globalData.goEasyConnection.autoReconnect = true;
  app.emitEvent('connectionChanged', { status: 'connecting' });

  const saved = getSavedConnection(app);
  if (saved && saved.userId === expectedId && saved.identityType === role) {
    connectWithIdentity(app, saved.identityType, saved.userId, true);
    return;
  }

  connectForCurrentRole(app);
}

async function ensureImForRole(app, role) {
  const uid = wx.getStorageSync('uid');
  if (!uid) throw new Error('未登录');
  const targetUserId = getImUserIdForRole(role, uid);
  if (!targetUserId) throw new Error('无效身份');

  if (isImConnected() && getCurrentGoEasyUserId() === targetUserId) {
    setupMessageListeners(app);
    loadConversations(app);
    syncConnectionStatus(app);
    return;
  }

  if (app.globalData.currentRole !== role) {
    app.globalData.currentRole = role;
    wx.setStorageSync('currentRole', role);
  }

  await connectWithIdentity(app, role, targetUserId, true);
}

function getSavedConnection(app) {
  try {
    const saved = wx.getStorageSync(app.globalData.goEasyConnection.cacheKeys.savedConnection);
    if (!saved) return null;
    if (typeof saved === 'string') return JSON.parse(saved);
    return saved;
  } catch (error) {
    console.error('获取保存的连接信息失败:', error);
    return null;
  }
}

function saveConnectionState(app) {
  try {
    const { goEasyConnection } = app.globalData;
    const connectionState = {
      userId: goEasyConnection.userId,
      identityType: goEasyConnection.identityType,
      lastConnectTime: Date.now(),
      autoReconnect: goEasyConnection.autoReconnect,
      status: goEasyConnection.status,
    };
    wx.setStorageSync(goEasyConnection.cacheKeys.savedConnection, JSON.stringify(connectionState));
  } catch (error) {
    console.warn('保存连接状态失败:', error);
  }
}

function clearSavedConnection(app) {
  const { cacheKeys } = app.globalData.goEasyConnection;
  wx.removeStorageSync(cacheKeys.savedConnection);
  wx.removeStorageSync(cacheKeys.userId);
  wx.removeStorageSync(cacheKeys.identityType);
  app.globalData.goEasyConnection.userId = '';
  app.globalData.goEasyConnection.identityType = '';
  app.globalData.goEasyConnection.lastConnectTime = 0;
}

function disconnectGoEasy(app, options = {}) {
  const silent = options.silent === true;
  const keepAutoReconnect = options.keepAutoReconnect === true;

  return withImLock(() => new Promise((resolve) => {
    if (silent) app._imSuppressDisconnectEvent = true;
    app.globalData.goEasyConnection.status = 'disconnected';
    if (!keepAutoReconnect) {
      app.globalData.goEasyConnection.autoReconnect = false;
    }
    stopHeartbeat(app);
    removeGlobalMessageListeners();

    const finish = () => {
      clearSavedConnection(app);
      if (!keepAutoReconnect) {
        app.globalData.messageManager.unreadTotal = 0;
        updateTabBarBadge(app, 0);
      }
      if (!silent) {
        app.emitEvent('connectionChanged', { status: 'disconnected', manual: true });
      }
      app._imSuppressDisconnectEvent = false;
      resolve();
    };

    if (wx.goEasy && wx.goEasy.disconnect) {
      wx.goEasy.disconnect({
        onSuccess: finish,
        onFailed: finish,
      });
    } else {
      finish();
    }
  }));
}

async function connectWithIdentity(app, identityType, userId, isAutoRestore = false) {
  if (!wx.goEasy?.connect) {
    return Promise.reject(new Error('聊天服务未就绪'));
  }

  return withImLock(async () => {
    if (!isAutoRestore) {
      const quanxian = await jianquanxian(app);
      if (!quanxian.allowed) {
        throw new Error(quanxian.reason || '无聊天权限');
      }
    } else {
      const uid = wx.getStorageSync('uid');
      if (!uid) throw new Error('未登录');
    }

    const currentId = getCurrentGoEasyUserId();
    if (isSdkConnected()) {
      if (!currentId || currentId === userId) {
        adoptExistingConnection(app, identityType, userId);
        return;
      }
      await disconnectGoEasy(app, { silent: true, keepAutoReconnect: true });
      app.globalData.goEasyConnection.autoReconnect = true;
      await new Promise((r) => setTimeout(r, 400));
    }

    if (currentId && currentId !== userId && !isSdkConnected()) {
      await disconnectGoEasy(app, { silent: true, keepAutoReconnect: true });
      app.globalData.goEasyConnection.autoReconnect = true;
      await new Promise((r) => setTimeout(r, 400));
    }

    app.globalData.goEasyConnection.autoReconnect = true;
    app.globalData.goEasyConnection.status = 'connecting';
    app.globalData.goEasyConnection.userId = userId;
    app.globalData.goEasyConnection.identityType = identityType;
    if (!isAutoRestore) app.globalData.goEasyConnection.reconnectAttempts = 0;
    saveConnectionState(app);
    app.emitEvent('connectionChanged', { status: 'connecting', identityType, userId });

    const uid = wx.getStorageSync('uid');
    const role = identityType || app.globalData.currentRole || 'normal';
    const freshUser = getFreshImUser(app, role, uid);
    const currentUser = app.globalData.currentUser || {
      id: uid,
      name: freshUser.name,
      avatar: freshUser.avatar,
    };

    return new Promise((resolve, reject) => {
      wx.goEasy.connect({
        id: userId,
        data: {
          name: freshUser.name || currentUser.name,
          avatar: freshUser.avatar || currentUser.avatar || (app.globalData.ossImageUrl + app.globalData.morentouxiang),
          identityType,
        },
        onSuccess: () => {
          app.globalData.goEasyConnection.status = 'connected';
          app.globalData.goEasyConnection.lastConnectTime = Date.now();
          app.globalData.goEasyConnection.reconnectAttempts = 0;
          saveConnectionState(app);
          startHeartbeat(app);
          setupMessageListeners(app);
          loadConversations(app);
          app.emitEvent('connectionChanged', { status: 'connected', identityType, userId });
          resolve();
        },
        onFailed: (error) => {
          console.error('GoEasy连接失败:', error);
          // 408 = 已连接，勿再 connect，直接复用当前连接
          if (error.code === 408) {
            adoptExistingConnection(app, identityType, userId);
            resolve();
            return;
          }
          if (error.code === 900) {
            app.globalData.goEasyConnection.autoReconnect = false;
            app.globalData.goEasyConnection.status = 'disconnected';
            clearSavedConnection(app);
            stopHeartbeat(app);
            wx.showModal({
              title: '消息功能暂不可用',
              content: '当前使用人数爆满，消息功能暂时无法使用。请联系管理员升级套餐后重试。',
              showCancel: false,
              confirmText: '我知道了',
            });
            app.emitEvent('connectionChanged', { status: 'disconnected', error, reason: 'overcapacity' });
            reject(error);
            return;
          }
          app.globalData.goEasyConnection.status = 'reconnecting';
          app.emitEvent('connectionChanged', { status: 'reconnecting', error, isAutoRestore });
          const { autoReconnect, reconnectAttempts, maxReconnectAttempts } = app.globalData.goEasyConnection;
          if (autoReconnect && reconnectAttempts < maxReconnectAttempts && !isSdkConnected()) {
            app.globalData.goEasyConnection.reconnectAttempts++;
            const delay = app.globalData.goEasyConnection.config.reconnectDelay * reconnectAttempts;
            setTimeout(() => {
              if (app.globalData.goEasyConnection.autoReconnect) {
                connectWithIdentity(app, identityType, userId, true).then(resolve).catch(reject);
              }
            }, delay);
          } else {
            reject(error);
          }
        },
      });
    });
  });
}

async function connectForCurrentRole(app) {
  const uid = wx.getStorageSync('uid');
  if (!uid) return;
  const role = app.globalData.currentRole || 'normal';
  const targetUserId = getImUserIdForRole(role, uid);

  const currentUserId = getCurrentGoEasyUserId();
  if (currentUserId === targetUserId && isImConnected()) {
    setupMessageListeners(app);
    startHeartbeat(app);
    loadConversations(app);
    syncConnectionStatus(app);
    return;
  }
  if (currentUserId && currentUserId !== targetUserId) {
    await disconnectGoEasy(app, { silent: true, keepAutoReconnect: true });
    app.globalData.goEasyConnection.autoReconnect = true;
  }
  await connectWithIdentity(app, role, targetUserId, true);
}

async function switchRoleAndReconnect(app, newRole) {
  try {
    await withImLock(async () => {
      await disconnectGoEasy(app, { silent: true, keepAutoReconnect: true });
      app.globalData.currentRole = newRole;
      wx.setStorageSync('currentRole', newRole);
      app.globalData.goEasyConnection.autoReconnect = true;
      app.globalData.goEasyConnection.reconnectAttempts = 0;
      const uid = wx.getStorageSync('uid');
      const targetUserId = getImUserIdForRole(newRole, uid);
      // 切换身份用轻量连接，避免鉴权接口失败把 IM 永久断开
      await connectWithIdentity(app, newRole, targetUserId, true);
    });
    return true;
  } catch (error) {
    console.warn('切换身份 IM 重连失败', error);
    syncConnectionStatus(app);
    throw error;
  }
}

function startHeartbeat(app) {
  const { goEasyConnection } = app.globalData;
  stopHeartbeat(app);
  let convTick = 0;
  goEasyConnection.heartbeatInterval = setInterval(() => {
    if (goEasyConnection.status === 'connected' && wx.goEasy?.im) {
      if (isSdkConnected()) {
        convTick += 1;
        if (convTick % 3 === 0) {
          loadConversations(app);
        }
      } else {
        goEasyConnection.status = 'reconnecting';
        app.emitEvent('connectionChanged', { status: 'reconnecting' });
        attemptReconnect(app);
      }
    } else if (goEasyConnection.autoReconnect && !isSdkConnected()) {
      ensureConnection(app);
    }
  }, goEasyConnection.config.heartbeatInterval);
}

function stopHeartbeat(app) {
  if (app.globalData.goEasyConnection.heartbeatInterval) {
    clearInterval(app.globalData.goEasyConnection.heartbeatInterval);
    app.globalData.goEasyConnection.heartbeatInterval = null;
  }
}

function pauseHeartbeat(app) { stopHeartbeat(app); }

function attemptReconnect(app) {
  const { goEasyConnection } = app.globalData;
  if (!goEasyConnection.autoReconnect || isSdkConnected()) return;
  if (goEasyConnection.reconnectAttempts >= goEasyConnection.maxReconnectAttempts) {
    goEasyConnection.reconnectAttempts = 0;
  }
  if (goEasyConnection.userId && goEasyConnection.identityType) {
    connectWithIdentity(app, goEasyConnection.identityType, goEasyConnection.userId, true);
  } else {
    connectForCurrentRole(app);
  }
}

function removeGlobalMessageListeners() {
  if (!wx.goEasy?.im) return;
  if (_globalPrivateHandler) {
    wx.goEasy.im.off(wx.GoEasy.IM_EVENT.PRIVATE_MESSAGE_RECEIVED, _globalPrivateHandler);
    _globalPrivateHandler = null;
  }
  if (_globalGroupHandler) {
    wx.goEasy.im.off(wx.GoEasy.IM_EVENT.GROUP_MESSAGE_RECEIVED, _globalGroupHandler);
    _globalGroupHandler = null;
  }
  if (_globalConvHandler) {
    wx.goEasy.im.off(wx.GoEasy.IM_EVENT.CONVERSATIONS_UPDATED, _globalConvHandler);
    _globalConvHandler = null;
  }
}

function setupMessageListeners(app) {
  if (!wx.goEasy?.im || typeof wx.goEasy.im.on !== 'function') {
    return;
  }
  removeGlobalMessageListeners();

  _globalPrivateHandler = (message) => {
    app.handleNewMessage(message);
  };
  _globalGroupHandler = (message) => {
    app.handleNewMessage(message);
  };
  _globalConvHandler = (conversations) => {
    const normalized = normalizeConversationPayload(conversations);
    const unreadTotal = normalized?.unreadTotal ?? conversations?.unreadTotal ?? 0;
    applyUnreadTotal(app, unreadTotal);
    if (normalized && typeof app.emitEvent === 'function') {
      app.emitEvent('conversationsUpdated', normalized);
    }
  };

  wx.goEasy.im.on(wx.GoEasy.IM_EVENT.PRIVATE_MESSAGE_RECEIVED, _globalPrivateHandler);
  wx.goEasy.im.on(wx.GoEasy.IM_EVENT.GROUP_MESSAGE_RECEIVED, _globalGroupHandler);
  wx.goEasy.im.on(wx.GoEasy.IM_EVENT.CONVERSATIONS_UPDATED, _globalConvHandler);
}

function handleNewMessage(app, message) {
  const messageId = message.messageId || message.id;
  const fingerprint = `${message.senderId}_${message.timestamp}_${message.type}`;
  const msgKey = messageId || fingerprint;

  if (!app._processedMessages) app._processedMessages = new Set();
  if (app._processedMessages.has(msgKey)) return;
  app._processedMessages.add(msgKey);
  if (app._processedMessages.size > 300) {
    app._processedMessages.delete(app._processedMessages.values().next().value);
  }

  cacheMessage(app, message);
  loadConversations(app);

  if (shouldShowNotification(app, message)) {
    let notificationType = 'private';
    let extraData = {};
    if (message.groupId) {
      notificationType = 'group';
      extraData = {
        groupId: message.groupId,
        orderId: message.orderId || '',
        groupName: '',
        groupAvatar: '',
        isCross: message.isCross || 0,
      };
      const groupInfo = app.globalData.groupInfoMap?.[message.groupId];
      if (groupInfo) {
        extraData.groupName = groupInfo.name || '';
        extraData.groupAvatar = groupInfo.avatar || '';
      }
    } else if (message.teamId) {
      notificationType = 'cs';
      extraData = { teamId: message.teamId };
    }
    showNotificationDirect(app, {
      senderId: message.senderId,
      senderName: message.senderData?.name || '用户',
      avatar: message.senderData?.avatar || (app.globalData.ossImageUrl + app.globalData.morentouxiang),
      content: formatMessageForNotification(message),
      message,
      notificationType,
      ...extraData,
    });
  }
}

function shouldShowNotification(app, message) {
  if (app.globalData.messageManager.notificationMuted) return false;
  if (isDoNotDisturbTime(app)) return false;
  if (isMessageFromCurrentChat(app, message)) return false;
  return true;
}

function isDoNotDisturbTime(app) {
  const { doNotDisturb, doNotDisturbStart, doNotDisturbEnd } = app.globalData.messageManager;
  if (!doNotDisturb) return false;
  const now = new Date();
  const currentTime = now.getHours() * 60 + now.getMinutes();
  const [sH, sM] = doNotDisturbStart.split(':').map(Number);
  const [eH, eM] = doNotDisturbEnd.split(':').map(Number);
  const startTime = sH * 60 + sM;
  const endTime = eH * 60 + eM;
  if (startTime < endTime) {
    return currentTime >= startTime && currentTime < endTime;
  }
  return currentTime >= startTime || currentTime < endTime;
}

function isMessageFromCurrentChat(app, message) {
  const pageState = app.globalData.pageState || {};
  if (!pageState.isInChatPage || !pageState.currentChatId) return false;
  if (message.groupId) {
    return message.groupId === pageState.currentChatId;
  }
  const myId = app.globalData.goEasyConnection?.userId || getCurrentGoEasyUserId();
  if (!myId) return false;
  const peerId = message.senderId === myId ? message.receiverId : message.senderId;
  return peerId === pageState.currentChatId || message.senderId === pageState.currentChatId;
}

function showNotificationDirect(app, data) {
  if (app.globalData.globalNotification?.show) {
    try {
      app.globalData.globalNotification.show(data);
      return;
    } catch (error) {
      console.warn('全局通知显示失败:', error);
    }
  }
  app.emitEvent('showNotification', data);
}

function startImWhenReady(app) {
  if (!wx.getStorageSync('uid')) return;
  app.globalData.goEasyConnection.autoReconnect = true;
  restoreCachedBadge(app);
  ensureConnection(app);
  setTimeout(() => {
    if (isSdkConnected()) {
      setupMessageListeners(app);
      loadConversations(app);
    }
    restoreCachedBadge(app);
  }, 450);
}

function restoreCachedBadge(app) {
  const { messageManager } = app.globalData;
  let unread = messageManager.unreadTotal;
  if (unread == null || unread === '') {
    try {
      const saved = wx.getStorageSync(messageManager.cacheKeys.unreadTotal);
      if (saved !== '' && saved != null) unread = Number(saved) || 0;
    } catch (e) {}
  }
  if (!unread) {
    try {
      const badgeStr = wx.getStorageSync('tabBarMessageBadge');
      if (badgeStr && badgeStr !== '0') {
        unread = badgeStr === '99+' ? 100 : (parseInt(badgeStr, 10) || 0);
      }
    } catch (e) {}
  }
  if (unread > 0) {
    updateTabBarBadge(app, unread);
  } else if (messageManager.tabBarBadgeText) {
    app.emitEvent('tabBarBadgeChanged', {
      index: messageManager.tabBarIndex,
      badgeText: messageManager.tabBarBadgeText,
      showRedDot: true,
      forceUpdate: true,
    });
    updateTabBarDirectly(app, messageManager.tabBarBadgeText);
  }
}

function applyUnreadTotal(app, unreadTotal) {
  const prev = app.globalData.messageManager.unreadTotal;
  const connected = isSdkConnected();
  if (unreadTotal === 0 && !connected && prev > 0) {
    restoreCachedBadge(app);
    return;
  }
  app.globalData.messageManager.unreadTotal = unreadTotal;
  updateTabBarBadge(app, unreadTotal);
  wx.setStorageSync(app.globalData.messageManager.cacheKeys.unreadTotal, unreadTotal);
  if (prev !== unreadTotal) {
    app.emitEvent('unreadCountChanged', { unreadTotal });
  }
}

async function updateUnreadCount(app, customCount) {
  let unreadTotal = customCount;
  if (unreadTotal === undefined) {
    try {
      const result = await getUnreadCount(app);
      unreadTotal = result.unreadTotal || 0;
    } catch (error) {
      console.error('获取未读数失败:', error);
      return;
    }
  }
  applyUnreadTotal(app, unreadTotal);
}

function getUnreadCount(app) {
  return new Promise((resolve, reject) => {
    if (!getCurrentGoEasyUserId()) {
      resolve({ unreadTotal: 0 });
      return;
    }
    wx.goEasy.im.latestConversations({
      onSuccess: (result) => resolve({
        unreadTotal: result.unreadTotal || 0,
        conversations: result.content?.conversations || [],
      }),
      onFailed: reject,
    });
  });
}

function formatMessageForNotification(message) {
  switch (message.type) {
    case 'text': return message.payload.text || '[文本]';
    case 'image': return '[图片]';
    case 'audio': return '[语音]';
    case 'video': return '[视频]';
    case 'file': return '[文件]';
    case 'order': return '[订单]';
    default: return '[新消息]';
  }
}

function cacheMessage(app, message) {
  if (message.groupId && message.type === 'text' && message.payload?.text) {
    const card = parseOrderCardText(message.payload.text);
    if (card && card.zhuangtai != null) {
      if (!app.globalData.groupInfoMap) app.globalData.groupInfoMap = {};
      const meta = {
        ...(app.globalData.groupInfoMap[message.groupId] || {}),
        orderId: card.orderId,
        orderZhuangtai: card.zhuangtai,
        orderDesc: card.jieshao,
      };
      app.globalData.groupInfoMap[message.groupId] = meta;
      persistGroupMeta(app, message.groupId, meta);
    }
  }
  const { latestMessages } = app.globalData.messageManager;
  latestMessages.unshift({
    id: message.messageId,
    type: message.type,
    senderId: message.senderId,
    senderName: message.senderData?.name,
    content: formatMessageForNotification(message),
    timestamp: message.timestamp || Date.now(),
    conversationId: message.conversationId,
  });
  if (latestMessages.length > 50) latestMessages.length = 50;
  wx.setStorageSync(app.globalData.messageManager.cacheKeys.latestMessages, latestMessages);
}

function normalizeConversationPayload(result) {
  if (!result) return null;
  const content = result.content || result;
  const list = content.conversations || result.conversations;
  if (!list || !Array.isArray(list)) return null;
  return {
    conversations: list,
    unreadTotal: content.unreadTotal ?? result.unreadTotal ?? 0,
  };
}

function loadConversations(app) {
  if (_loadConvTimer) clearTimeout(_loadConvTimer);
  _loadConvTimer = setTimeout(() => {
    _loadConvTimer = null;
    loadConversationsNow(app);
  }, 280);
}

function loadConversationsNow(app) {
  if (_loadConvInFlight) return;
  if (!isSdkConnected() || !wx.goEasy?.im?.latestConversations) {
    restoreCachedBadge(app);
    if (app.globalData.goEasyConnection.autoReconnect) {
      ensureConnection(app);
    }
    return;
  }
  _loadConvInFlight = true;
  wx.goEasy.im.latestConversations({
    onSuccess: (result) => {
      _loadConvInFlight = false;
      const normalized = normalizeConversationPayload(result);
      if (result.unreadTotal !== undefined) {
        applyUnreadTotal(app, result.unreadTotal);
      } else if (normalized) {
        applyUnreadTotal(app, normalized.unreadTotal);
      }
      if (normalized && typeof app.emitEvent === 'function') {
        app.emitEvent('conversationsUpdated', normalized);
      }
      const conversations = normalized?.conversations || [];
      if (!app.globalData.groupInfoMap) app.globalData.groupInfoMap = {};
      conversations.forEach((c) => {
        if (c.type === 'group' && c.groupId) {
          app.globalData.groupInfoMap[c.groupId] = c.data || {};
        }
      });
      _ensureGroupSubscriptions(app, conversations);
    },
    onFailed: (error) => {
      _loadConvInFlight = false;
      console.error('加载会话列表失败:', error);
      restoreCachedBadge(app);
      if (!isSdkConnected() && app.globalData.goEasyConnection.autoReconnect) {
        attemptReconnect(app);
      }
    },
  });
}

function _ensureGroupSubscriptions(app, conversations) {
  const groupIds = conversations
    .filter((c) => c.type === 'group' && c.groupId)
    .map((c) => c.groupId);

  if (groupIds.length === 0) return;
  if (!wx.goEasy?.im || typeof wx.goEasy.im.subscribeGroup !== 'function') return;

  wx.goEasy.im.subscribeGroup({
    groupIds,
    onSuccess: () => {},
    onFailed: (error) => console.error('全局订阅群组失败:', error),
  });
}

function updateCurrentPageState(app) {
  try {
    const pages = getCurrentPages();
    if (pages.length > 0) {
      const currentPage = pages[pages.length - 1];
      const chatPages = [
        'pages/chat/chat',
        'pages/group-chat/group-chat',
        'pages/cs-chat/cs-chat',
        'pages/liaotian/liaotian',
        'pages/qunliaotian/qunliaotian',
        'pages/kefuliaotian/kefuliaotian',
      ];
      app.globalData.pageState.currentPage = currentPage.route;
      app.globalData.pageState.isInChatPage = chatPages.indexOf(currentPage.route) >= 0;
      app.globalData.pageState.lastPageUpdate = Date.now();
    }
  } catch (error) {
    console.warn('更新页面状态失败:', error);
  }
}

function saveUserSettings(app) {
  try {
    wx.setStorageSync(app.globalData.messageManager.cacheKeys.messageSettings, {
      soundEnabled: app.globalData.messageManager.soundEnabled,
      vibrationEnabled: app.globalData.messageManager.vibrationEnabled,
      doNotDisturb: app.globalData.messageManager.doNotDisturb,
      doNotDisturbStart: app.globalData.messageManager.doNotDisturbStart,
      doNotDisturbEnd: app.globalData.messageManager.doNotDisturbEnd,
      notificationMuted: app.globalData.messageManager.notificationMuted,
      notificationStyle: app.globalData.messageManager.notificationStyle,
    });
  } catch (error) {
    console.warn('保存用户设置失败:', error);
  }
}

function toggleDoNotDisturb(app, enabled) {
  app.globalData.messageManager.doNotDisturb = enabled;
  saveUserSettings(app);
  wx.showToast({ title: `免打扰${enabled ? '开启' : '关闭'}`, icon: 'success', duration: 2000 });
}

function toggleNotificationMute(app, enabled) {
  app.globalData.messageManager.notificationMuted = enabled;
  wx.setStorageSync(app.globalData.messageManager.cacheKeys.notificationMuted, enabled);
  saveUserSettings(app);
  wx.showToast({ title: `通知${enabled ? '静音' : '开启'}`, icon: 'success', duration: 2000 });
}

function closeNotification(app) {
  app.emitEvent('hideNotification');
}

function updateTabBarBadge(app, unreadCount) {
  const { messageManager } = app.globalData;
  if (!messageManager.showTabBarBadge) return;
  let badgeText = '';
  if (unreadCount > 0) {
    badgeText = unreadCount > 99 ? '99+' : unreadCount.toString();
  }
  messageManager.tabBarBadgeText = badgeText;
  app.emitEvent('tabBarBadgeChanged', {
    index: messageManager.tabBarIndex,
    badgeText,
    showRedDot: unreadCount > 0,
    forceUpdate: true,
  });
  updateTabBarDirectly(app, badgeText);
  saveTabBarBadgeToStorage(app, badgeText);
}

function updateTabBarDirectly(app, badgeText) {
  try {
    const pages = getCurrentPages();
    for (let i = pages.length - 1; i >= 0; i--) {
      const tabBar = pages[i].selectComponent('#custom-tab-bar')
        || pages[i].selectComponent('tab-bar');
      if (tabBar && tabBar.setData) {
        tabBar.setData({ badgeText });
        break;
      }
    }
  } catch (error) { console.warn('直接更新TabBar失败:', error); }
}

function saveTabBarBadgeToStorage(app, badgeText) {
  try {
    wx.setStorageSync('tabBarMessageBadge', badgeText);
  } catch (error) { console.warn('保存TabBar徽章失败:', error); }
}

module.exports = { initGlobalMessageSystem };
