/**
 * 订单群聊跳转：先确定群 ID，IM 连接失败也尽量能进聊天页
 */
import request from './request';
import { persistGroupMeta } from './im-user.js';
import { resolveLocalGroupId } from './group-chat.js';

const app = getApp();

function formatError(err) {
  if (!err) return '进入聊天失败';
  if (typeof err === 'string') return err;
  if (err.message) return err.message;
  if (err.content) return String(err.content);
  if (err.msg) return String(err.msg);
  if (err.code) return `连接失败(${err.code})`;
  try {
    return JSON.stringify(err);
  } catch (e) {
    return '进入聊天失败';
  }
}

function withTimeout(promise, ms, errMsg) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => reject(new Error(errMsg || '操作超时')), ms);
    promise
      .then((v) => { clearTimeout(timer); resolve(v); })
      .catch((e) => { clearTimeout(timer); reject(e); });
  });
}

function getConnectedUserId() {
  const fromState = app.globalData?.goEasyConnection?.userId;
  const fromIm = wx.goEasy?.im?.userId;
  return fromState || fromIm || '';
}

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

async function ensureIdentityConnection(identityType, userId) {
  app.globalData.currentRole = identityType;
  wx.setStorageSync('currentRole', identityType);

  const uid = userId.replace(/^(Ds|Sj|Boss|Gs|Zz|Kh)/, '');
  const avatar = wx.getStorageSync('touxiang') ||
    (app.globalData.ossImageUrl + app.globalData.morentouxiang);
  app.globalData.currentUser = {
    id: userId,
    name: app.globalData.currentUser?.name || `用户${uid}`,
    avatar: avatar,
  };

  if (!app.globalData.chatEnabled || !wx.goEasy?.im) {
    throw new Error('聊天服务未就绪，请稍后重试');
  }

  if (isImConnected() && getConnectedUserId() === userId) {
    return;
  }

  const connectedId = getConnectedUserId();
  if (connectedId && connectedId !== userId && app.disconnectGoEasy) {
    await app.disconnectGoEasy();
  }

  if (!app.connectWithIdentity) {
    throw new Error('聊天功能未初始化');
  }

  await withTimeout(
    app.connectWithIdentity(identityType, userId, true),
    12000,
    'IM连接超时'
  );

  if (!isImConnected()) {
    throw new Error('IM连接失败，请检查网络后重试');
  }
}

async function prepareGroupChat(identityType, userId, orderId, partnerUid, fadanPingtai, groupName, isCross) {
  let chatData = null;

  try {
    const res = await withTimeout(
      request({
        url: '/dingdan/ltdhzb',
        method: 'POST',
        data: {
          dingdan_id: orderId,
          identityType,
          push_order_card: true,
        },
      }),
      12000,
      '准备群聊超时'
    );
    const body = res?.data || {};
    if (body.code === 0 && body.data?.groupId) {
      chatData = body.data;
    } else if (body.msg) {
      console.warn('ltdhzb:', body.msg);
    }
  } catch (e) {
    console.warn('ltdhzb 请求失败，尝试本地 groupId', e);
  }

  if (!chatData?.groupId) {
    const myUid = userId.replace(/^(Ds|Sj|Boss)/, '');
    let localGroupId = resolveLocalGroupId(
      identityType, myUid, partnerUid, fadanPingtai, orderId, isCross
    );
    if (!localGroupId && orderId) {
      localGroupId = `group_${orderId}`;
    }
    if (!localGroupId) {
      throw new Error('无法确定群聊，请确认订单已接单且对方信息完整');
    }
    chatData = {
      groupId: localGroupId,
      orderId,
      groupName: groupName || '订单群聊',
      isCross: isCross || fadanPingtai || 0,
    };
    try {
      await request({
        url: '/dingdan/ltdhzb',
        method: 'POST',
        data: { dingdan_id: orderId, identityType, push_order_card: true },
      });
    } catch (e) { /* ignore */ }
  }

  return chatData;
}

class ConnectionManager {
  async connectAndChat(params) {
    const { identityType, userId, targetUser } = params;
    if (!identityType || !userId || !targetUser || !targetUser.id) {
      throw new Error('参数不完整');
    }

    await ensureIdentityConnection(identityType, userId);

    const currentUser = {
      id: userId,
      name: app.globalData.currentUser?.name || '用户',
      avatar: app.globalData.currentUser?.avatar || (app.globalData.ossImageUrl + app.globalData.morentouxiang),
    };

    const to = {
      id: targetUser.id,
      name: targetUser.name || '用户',
      avatar: targetUser.avatar || (app.globalData.ossImageUrl + app.globalData.morentouxiang),
    };

    const param = { to, currentUser };
    wx.navigateTo({ url: '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param)) });
  }

  async connectToGroupChat(params) {
    const {
      identityType, userId, orderId, groupName, groupAvatar, isCross,
      partnerUid, fadanPingtai,
    } = params;

    if (!identityType || !userId || !orderId) {
      throw new Error('参数不完整');
    }

    app.globalData.currentRole = identityType;
    wx.setStorageSync('currentRole', identityType);

    wx.showLoading({ title: '建立联系中...', mask: true });

    try {
      const chatData = await prepareGroupChat(
        identityType, userId, orderId, partnerUid, fadanPingtai || isCross, groupName, isCross
      );

      const realGroupId = chatData.groupId;
      let avatar = chatData.counterpartAvatar || chatData.groupAvatar || groupAvatar || '';
      if (avatar && !avatar.startsWith('http')) {
        avatar = app.globalData.ossImageUrl + avatar.replace(/^\//, '');
      }

      if (!app.globalData.groupInfoMap) app.globalData.groupInfoMap = {};
      const meta = {
        name: chatData.counterpartName || chatData.groupName || groupName,
        avatar,
        orderId: chatData.orderId || orderId,
        orderDesc: chatData.orderDesc || '',
        orderZhuangtai: chatData.orderZhuangtai,
        dashouGoEasyId: chatData.dashouGoEasyId,
        partnerGoEasyId: chatData.partnerGoEasyId,
        dashouYonghuid: chatData.dashouYonghuid,
        partnerYonghuid: chatData.partnerYonghuid,
        dashouName: chatData.dashouName,
        partnerName: chatData.partnerName,
        dashouAvatar: chatData.dashouAvatar,
        partnerAvatar: chatData.partnerAvatar,
        counterpartId: chatData.counterpartId,
        counterpartYonghuid: chatData.counterpartYonghuid,
      };
      app.globalData.groupInfoMap[realGroupId] = meta;
      persistGroupMeta(app, realGroupId, meta);

      let imReady = false;
      try {
        await ensureIdentityConnection(identityType, userId);
        imReady = true;
        try {
          await withTimeout(
            new Promise((resolve, reject) => {
              wx.goEasy.im.subscribeGroup({
                groupIds: [realGroupId],
                onSuccess: () => resolve(),
                onFailed: (error) => reject(error),
              });
            }),
            8000,
            '订阅群聊超时'
          );
        } catch (subErr) {
          console.warn('订阅群聊失败，仍尝试进入页面', subErr);
        }
      } catch (imErr) {
        console.warn('IM连接失败，仍进入聊天页由页面重连', imErr);
      }

      const uid = userId.replace(/^(Ds|Sj|Boss)/, '');
      const param = {
        groupId: realGroupId,
        orderId: chatData.orderId || orderId,
        groupName: chatData.counterpartName || chatData.groupName || groupName || '订单群聊',
        groupAvatar: avatar,
        isCross: chatData.isCross != null ? chatData.isCross : (isCross || 0),
        currentUserId: userId,
        currentUserName: app.globalData.currentUser?.name || `用户${uid}`,
        currentUserAvatar: app.globalData.currentUser?.avatar ||
          (wx.getStorageSync('touxiang') || (app.globalData.ossImageUrl + app.globalData.morentouxiang)),
        orderZhuangtai: chatData.orderZhuangtai,
        orderJine: chatData.orderJine,
        orderDesc: chatData.orderDesc || '',
        imReady,
      };

      wx.hideLoading();
      wx.navigateTo({
        url: '/pages/qunliaotian/qunliaotian?data=' + encodeURIComponent(JSON.stringify(param)),
        fail: (navErr) => {
          wx.showToast({ title: formatError(navErr), icon: 'none', duration: 2500 });
        },
      });
    } catch (err) {
      wx.hideLoading();
      console.error('跳转群聊失败:', err);
      wx.showToast({ title: formatError(err), icon: 'none', duration: 2500 });
      throw err;
    }
  }
}

export default new ConnectionManager();
