const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
const db = cloud.database()
const _ = db.command

function formatTimeText(ts) {
  if (!ts) return ''
  const diff = Date.now() - ts
  const mins = Math.floor(diff / 60000)
  if (mins < 1) return '现在'
  if (mins < 60) return `${mins} 分钟前`
  const hours = Math.floor(mins / 60)
  if (hours < 24) return `${hours} 小时前`
  const days = Math.floor(hours / 24)
  if (days === 1) return '昨天'
  const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  if (days < 7) return weekdays[new Date(ts).getDay()]
  const d = new Date(ts)
  return `${d.getMonth() + 1}/${d.getDate()}`
}

// Query a collection that may not exist yet (created lazily on first write).
async function safeGet(collection, where, limit = 200) {
  try {
    return await db.collection(collection).where(where).limit(limit).get()
  } catch (e) {
    return { data: [] }
  }
}

async function fetchUsers(ids) {
  if (!ids.length) return []
  const out = []
  for (let i = 0; i < ids.length; i += 100) {
    const chunk = ids.slice(i, i + 100)
    const res = await db.collection('users').where({ _id: _.in(chunk) }).limit(100).get()
    out.push(...res.data)
  }
  return out
}

async function fetchUsersByOpenids(openids) {
  if (!openids.length) return []
  const out = []
  for (let i = 0; i < openids.length; i += 100) {
    const chunk = openids.slice(i, i + 100)
    const res = await db.collection('users').where({ openid: _.in(chunk) }).limit(100).get()
    out.push(...res.data)
  }
  return out
}

exports.main = async event => {
  const { OPENID } = cloud.getWXContext()
  if (!OPENID) throw new Error('no openid in wx context')
  const tab = event.tab || 'all'
  const query = { memberOpenids: OPENID }
  if (tab === 'groups') query.type = 'group'
  if (tab === 'unread') query.unreadOpenids = OPENID

  const meRes = await db.collection('users').where({ openid: OPENID }).limit(1).get()
  const meId = meRes.data[0] && meRes.data[0]._id

  // Active row = my 汪友 (mutual follows)
  let friendUsers = []
  if (meId) {
    const [followingRes, followerRes] = await Promise.all([
      safeGet('follows', { followerId: meId }, 500),
      safeGet('follows', { followeeId: meId }, 500)
    ])
    const followerSet = new Set(followerRes.data.map(f => f.followerId))
    const friendIds = followingRes.data.map(f => f.followeeId).filter(id => followerSet.has(id))
    friendUsers = await fetchUsers(friendIds)
  }

  let convRes
  try {
    convRes = await db.collection('conversations').where(query).orderBy('updatedAt', 'desc').limit(50).get()
  } catch (e) {
    convRes = { data: [] }
  }

  const peerOpenids = [
    ...new Set(
      convRes.data
        .filter(c => (c.type || 'single') === 'single')
        .map(c => (c.memberOpenids || []).find(memberOpenid => memberOpenid !== OPENID))
        .filter(Boolean)
    )
  ]
  const peerUsers = await fetchUsersByOpenids(peerOpenids)
  const peerUserByOpenid = new Map(peerUsers.map(user => [user.openid, user]))

  const conversations = convRes.data.map(c => {
    const unreadOpenids = c.unreadOpenids || []
    const unreadCounts = c.unreadCounts || {}
    const unreadCount = unreadCounts[OPENID] || (unreadOpenids.includes(OPENID) ? 1 : 0)
    const type = c.type || 'single'
    const peerOpenid = type === 'single'
      ? (c.memberOpenids || []).find(memberOpenid => memberOpenid !== OPENID)
      : ''
    const peer = peerOpenid ? peerUserByOpenid.get(peerOpenid) : null

    return {
      _id: c._id,
      type,
      title: type === 'single'
        ? peer?.nickname || c.title || '未知用户'
        : c.title || '系统消息',
      petName: c.petName || undefined,
      avatarKey: type === 'single'
        ? peer?.avatarKey || c.avatarKey || 'gradient-avatar-1'
        : c.avatarKey || 'gradient-avatar-1',
      avatarUrl: type === 'single'
        ? peer?.avatarUrl || c.avatarUrl || ''
        : c.avatarUrl || '',
      preview: c.lastMessage?.content || c.preview || '',
      timeText: formatTimeText(c.updatedAt || c.createdAt),
      unreadCount,
      pinned: Boolean(c.pinned),
      muted: Boolean(c.muted),
      online: type === 'single' ? Boolean(peer?.online || c.online) : Boolean(c.online)
    }
  })

  const activeUsers = friendUsers.map(u => ({
    id: u._id,
    name: u.nickname || '汪友',
    avatarKey: u.avatarKey || 'gradient-avatar-1',
    avatarUrl: u.avatarUrl || '',
    live: Boolean(u.online)
  }))

  return { activeUsers, conversations }
}
