// utils/chat-core.js
import GoEasy from '../static/lib/goeasy-2.13.24.esm.min';
import { jianquanxian } from './imAuth/jianquanxian';
import { getFreshImUser } from './im-user.js';

let _globalPrivateHandler = null;
let _globalGroupHandler = null;
let _globalConvHandler = null;

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);

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

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

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

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

function initAppStateListener(app) {
  wx.onAppShow(() => {
    ensureConnection(app);
    updateCurrentPageState(app);
    // ✅ 连接正常时，主动刷一次未读角标
    if (wx.goEasy.getConnectionStatus && wx.goEasy.getConnectionStatus() === 'connected') {
        loadConversations(app);
      }
  });
  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);
      } else {
        ensureConnection(app);
      }
    }
  } catch (error) {
    console.warn('检查保存的连接信息失败:', error);
  }
}

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

// 🔥 修改点：不依赖 saved 缓存，只要连接状态正常就刷新角标
function ensureConnection(app) {
  const connectionStatus = wx.goEasy.getConnectionStatus ? wx.goEasy.getConnectionStatus() : 'disconnected';
  if (connectionStatus === 'connected' || connectionStatus === 'reconnected') {
    setupMessageListeners(app);
    loadConversations(app);        // 每次进入前台都刷新未读
    return;
  }

  // 连接不存在时尝试恢复
  const saved = getSavedConnection(app);
  if (!saved || !saved.userId || !saved.identityType) return;

  connectWithIdentity(app, saved.identityType, saved.userId, 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) {
  return new Promise((resolve) => {
    app.globalData.goEasyConnection.status = 'disconnected';
    app.globalData.goEasyConnection.autoReconnect = false;
    stopHeartbeat(app);
    removeGlobalMessageListeners();
    if (wx.goEasy && wx.goEasy.disconnect) {
      wx.goEasy.disconnect({
        onSuccess: () => {
          clearSavedConnection(app);
          app.globalData.messageManager.unreadTotal = 0;
          updateTabBarBadge(app, 0);
          app.emitEvent('connectionChanged', { status: 'disconnected', manual: true });
          resolve();
        },
        onFailed: () => {
          clearSavedConnection(app);
          app.globalData.messageManager.unreadTotal = 0;
          updateTabBarBadge(app, 0);
          resolve();
        }
      });
    } else {
      clearSavedConnection(app);
      app.globalData.messageManager.unreadTotal = 0;
      updateTabBarBadge(app, 0);
      resolve();
    }
  });
}

async function connectWithIdentity(app, identityType, userId, isAutoRestore = false) {
  const quanxian = await jianquanxian(app);
  if (!quanxian.allowed) return Promise.reject(quanxian.reason);

  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);

  const uid = wx.getStorageSync('uid');
  const role = app.globalData.currentRole || identityType || '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 });
        if (!isAutoRestore) {
          wx.showToast({ title: '连接成功', icon: 'success', duration: 2000 });
        }
        resolve();
      },
      onFailed: (error) => {
        console.error('GoEasy连接失败:', error);
        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 = 'disconnected';
        app.emitEvent('connectionChanged', { status: 'disconnected', error, isAutoRestore });
        const { autoReconnect, reconnectAttempts, maxReconnectAttempts } = app.globalData.goEasyConnection;
        if (autoReconnect && reconnectAttempts < maxReconnectAttempts) {
          app.globalData.goEasyConnection.reconnectAttempts++;
          setTimeout(() => {
            if (app.globalData.goEasyConnection.autoReconnect) {
              connectWithIdentity(app, identityType, userId, true);
            }
          }, app.globalData.goEasyConnection.config.reconnectDelay);
          reject(error);
        } else {
          reject(error);
        }
      },
    });
  });
}

function connectForCurrentRole(app) {
  const uid = wx.getStorageSync('uid');
  if (!uid) return;
  const role = app.globalData.currentRole || 'normal';
  const prefixMap = { normal: 'Boss', dashou: 'Ds', shangjia: 'Sj', guanshi: 'Gs', zuzhang: 'Zz' , kaoheguan: 'Kh'};
  const prefix = prefixMap[role] || 'Boss';
  const targetUserId = prefix + uid;

  const currentUserId = getCurrentGoEasyUserId();
  if (currentUserId === targetUserId) {
    loadConversations(app);
    setupMessageListeners(app);
    return;
  }
  if (currentUserId) {
    wx.goEasy.disconnect({ onSuccess: () => {}, onFailed: () => {} });
  }
  connectWithIdentity(app, role, targetUserId, false);
}

async function switchRoleAndReconnect(app, newRole) {
  try {
    await disconnectGoEasy(app);
    app.globalData.currentRole = newRole;
    wx.setStorageSync('currentRole', newRole);
    const uid = wx.getStorageSync('uid');
    const prefixMap = { normal: 'Boss', dashou: 'Ds', shangjia: 'Sj', guanshi: 'Gs', zuzhang: 'Zz' , kaoheguan: 'Kh'};
    const prefix = prefixMap[newRole] || 'Boss';
    const targetUserId = prefix + uid;
    await connectWithIdentity(app, newRole, targetUserId, false);
    return true;
  } catch (error) {
    wx.showToast({ title: '聊天功能不可用，可能是人数爆满或未充值会员', icon: 'none' });
    throw error;
  }
}

function startHeartbeat(app) {
  const { goEasyConnection } = app.globalData;
  stopHeartbeat(app);
  goEasyConnection.heartbeatInterval = setInterval(() => {
    if (goEasyConnection.status === 'connected' && wx.goEasy?.im) {
      wx.goEasy.im.ping({
        onSuccess: () => {},
        onFailed: (error) => {
          console.error('心跳失败:', error);
          goEasyConnection.status = 'reconnecting';
          attemptReconnect(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) return;
  if (goEasyConnection.userId && goEasyConnection.identityType) {
    connectWithIdentity(app, goEasyConnection.identityType, goEasyConnection.userId, true);
  }
}

/* ---------- 消息监听器 ---------- */
function removeGlobalMessageListeners() {
  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) {
  removeGlobalMessageListeners();

  _globalPrivateHandler = (message) => {
    app.handleNewMessage(message);
  };
  _globalGroupHandler = (message) => {
    app.handleNewMessage(message);
  };
  _globalConvHandler = (conversations) => {
    const unreadTotal = conversations.unreadTotal || 0;
    app.globalData.messageManager.unreadTotal = unreadTotal;
    updateTabBarBadge(app, unreadTotal);
    wx.setStorageSync(app.globalData.messageManager.cacheKeys.unreadTotal, unreadTotal);
    if (typeof app.emitEvent === 'function') {
      app.emitEvent('conversationsUpdated', conversations);
    }
  };

  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 > 200) {
    app._processedMessages.delete(app._processedMessages.values().next().value);
  }

  const now = Date.now();
  const msgTime = message.timestamp || now;
  if (now - msgTime > 60000) {
    cacheMessage(app, message);
    return;
  }

  cacheMessage(app, message);

  if (shouldShowNotification(app)) {
    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) {
  if (app.globalData.messageManager.notificationMuted) return false;
  if (isDoNotDisturbTime(app)) return false;
  if (app.globalData.pageState.isInChatPage) {
    const pages = getCurrentPages();
    if (pages.length > 0) {
      const currentPage = pages[pages.length - 1];
      if (currentPage.data && currentPage.data.currentChatId) {
        if (isMessageFromCurrentChat(app, currentPage.data.currentChatId)) 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;
  } else {
    return currentTime >= startTime || currentTime < endTime;
  }
}

function isMessageFromCurrentChat(app, currentChatId) {
  return false;
}

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);
}

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;
    }
  }
  app.globalData.messageManager.unreadTotal = unreadTotal;
  updateTabBarBadge(app, unreadTotal);
  wx.setStorageSync(app.globalData.messageManager.cacheKeys.unreadTotal, unreadTotal);
  app.emitEvent('unreadCountChanged', { 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) {
  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 loadConversations(app) {
  if (!getCurrentGoEasyUserId()) return;
  wx.goEasy.im.latestConversations({
    onSuccess: (result) => {
      if (result.unreadTotal !== undefined) {
        updateUnreadCount(app, result.unreadTotal);
      }
      app.emitEvent('conversationsUpdated', result);
      const conversations = result?.content?.conversations || result?.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) => console.error('加载会话列表失败:', error),
  });
}

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') {
    console.error('subscribeGroup 不可用');
    return;
  }

  wx.goEasy.im.subscribeGroup({
    groupIds: 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/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();
    if (pages.length > 0) {
      const tabBar = pages[pages.length - 1].selectComponent('#custom-tab-bar');
      if (tabBar && tabBar.setData) tabBar.setData({ badgeText });
    }
  } catch (error) { console.warn('直接更新TabBar失败:', error); }
}

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

module.exports = { initGlobalMessageSystem };