/**
 * 聊天历史消息加载（私聊 / 群聊 / 客服共用）
 * - 排除本地/欢迎语等合成消息的 timestamp，避免下拉加载错位
 * - 统一 IM 连接等待与 history API 封装
 */

const SYNTHETIC_MSG_ID = /^(local-|img-|order-|welcome-|auto-reply-)/;

export function isHistorySyntheticMessage(msg) {
  return !!(msg && msg.messageId && SYNTHETIC_MSG_ID.test(String(msg.messageId)));
}

/** 取当前列表里最早一条「真实」服务端消息的时间戳，供 GoEasy history 分页 */
export function getOldestHistoryTimestamp(messages, fallback = null) {
  if (!Array.isArray(messages)) return fallback;
  let oldest = null;
  for (const m of messages) {
    if (!m || m.timestamp == null) continue;
    if (isHistorySyntheticMessage(m)) continue;
    if (oldest == null || m.timestamp < oldest) oldest = m.timestamp;
  }
  return oldest != null ? oldest : fallback;
}

/** 等待 IM 连接就绪（优先 ensureImForRole，避免未连上就拉历史） */
export async function waitChatImReady(app, timeoutMs = 12000) {
  const role = app?.globalData?.currentRole || 'normal';
  if (app?.ensureImForRole) {
    try {
      await app.ensureImForRole(role);
      if (isImConnected()) return true;
    } catch (e) {
      console.warn('[IM] ensureImForRole failed', e);
    }
  }
  if (app?.ensureConnection) app.ensureConnection();
  return waitImConnected(app, timeoutMs);
}

export function isImConnected() {
  const status = wx.goEasy?.getConnectionStatus?.() || 'disconnected';
  return (status === 'connected' || status === 'reconnected') && !!wx.goEasy?.im;
}

/** 等待 IM 连接就绪（下拉加载历史前必须先连上） */
export function waitImConnected(app, timeoutMs = 8000) {
  return new Promise((resolve) => {
    if (isImConnected()) {
      resolve(true);
      return;
    }
    if (app?.ensureConnection) app.ensureConnection();
    const start = Date.now();
    const timer = setInterval(() => {
      if (isImConnected()) {
        clearInterval(timer);
        resolve(true);
      } else if (Date.now() - start >= timeoutMs) {
        clearInterval(timer);
        resolve(false);
      }
    }, 200);
  });
}

export function fetchHistoryMessages({ scene, id, lastTimestamp, limit = 20 }) {
  return new Promise((resolve, reject) => {
    if (!wx.goEasy?.im?.history) {
      reject(new Error('IM未初始化'));
      return;
    }
    if (!id) {
      reject(new Error('会话ID为空'));
      return;
    }
    wx.goEasy.im.history({
      type: scene,
      id: String(id),
      lastTimestamp: lastTimestamp ?? null,
      limit,
      onSuccess: (res) => resolve(res?.content || []),
      onFailed: (err) => reject(err || new Error('加载历史消息失败')),
    });
  });
}

/**
 * 合并一页历史消息
 * @returns {{ messages, hasMore, lastTimestamp }}
 */
export function mergeHistoryMessages({ incoming, existing, refresh, limit = 20, mapMessage }) {
  let list = Array.isArray(incoming) ? [...incoming] : [];
  list.sort((a, b) => a.timestamp - b.timestamp);
  if (typeof mapMessage === 'function') {
    list = list.map((m, idx) => mapMessage(m, idx, list));
  }

  const prev = Array.isArray(existing) ? existing : [];
  let final = refresh ? list : [...list, ...prev];

  if (!refresh) {
    for (let i = 0; i < final.length; i += 1) {
      if (i === 0) final[i].showTime = true;
      else final[i].showTime = (final[i].timestamp - final[i - 1].timestamp) / 60000 > 5;
    }
  }

  const ids = new Set();
  const unique = [];
  for (const m of final) {
    if (!m?.messageId || ids.has(m.messageId)) continue;
    ids.add(m.messageId);
    unique.push(m);
  }

  return {
    messages: unique,
    hasMore: list.length >= limit,
    lastTimestamp: getOldestHistoryTimestamp(unique, null),
  };
}
