import Member from '../../models/member.js'
import Connection from '../../models/connection.js'
import { requireAuth } from '../../utils/auth.js'

export default defineEventHandler(async (event) => {
  const member = await requireAuth(event)
  const memberId = member._id

  const topics = member.communityConnections?.topics || []
  if (!topics.length) {
    return { suggestions: [] }
  }

  const query = getQuery(event)
  const filterTag = query.tag || null
  const filterState = query.state || null
  const showHidden = query.showHidden === 'true'

  // Build the set of tag slugs to match against
  let myTopics = topics
  if (filterTag) {
    myTopics = myTopics.filter(t => t.tagSlug === filterTag)
  }
  if (filterState) {
    myTopics = myTopics.filter(t => t.state === filterState)
  }
  if (!myTopics.length) {
    return { suggestions: [] }
  }

  const mySlugs = myTopics.map(t => t.tagSlug)

  // Find active members sharing at least one topic slug
  const candidates = await Member.find({
    _id: { $ne: memberId },
    status: 'active',
    'communityConnections.topics.tagSlug': { $in: mySlugs }
  })
    .select('name avatar craftTags circle communityConnections privacy')
    .lean()

  if (!candidates.length) {
    return { suggestions: [] }
  }

  const candidateIds = candidates.map(c => c._id)

  // Find existing connections (pending or confirmed) to exclude
  const existingConnections = await Connection.find({
    $or: [
      { initiator: memberId, recipient: { $in: candidateIds } },
      { recipient: memberId, initiator: { $in: candidateIds } }
    ]
  })
    .select('initiator recipient hiddenBy status')
    .lean()

  // Build sets for exclusion
  const excludeIds = new Set()
  for (const conn of existingConnections) {
    const otherId = conn.initiator.toString() === memberId.toString()
      ? conn.recipient.toString()
      : conn.initiator.toString()

    // Exclude if confirmed or pending connection exists
    if (conn.status === 'confirmed' || conn.status === 'pending') {
      excludeIds.add(otherId)
    }
    // Exclude if current member has hidden this connection (unless showHidden)
    if (!showHidden && conn.hiddenBy?.some(id => id.toString() === memberId.toString())) {
      excludeIds.add(otherId)
    }
  }

  // Build topic lookup for current member (using filtered topics)
  const myTopicMap = {}
  for (const t of myTopics) {
    myTopicMap[t.tagSlug] = t.state
  }

  // Compute suggestions
  const suggestions = []
  for (const candidate of candidates) {
    if (excludeIds.has(candidate._id.toString())) continue

    const theirTopics = candidate.communityConnections?.topics || []
    const matchingTags = []

    for (const theirTopic of theirTopics) {
      const myState = myTopicMap[theirTopic.tagSlug]
      if (!myState) continue

      matchingTags.push({
        tagSlug: theirTopic.tagSlug,
        yourState: myState,
        theirState: theirTopic.state
      })
    }

    if (!matchingTags.length) continue

    // Apply privacy filtering — only expose fields the member allows for other members
    const privacy = candidate.privacy || {}
    const filtered = {
      _id: candidate._id,
      name: candidate.name,
      circle: candidate.circle,
    }

    const avatarPrivacy = privacy.avatar || 'public'
    if (avatarPrivacy === 'public' || avatarPrivacy === 'members') {
      filtered.avatar = candidate.avatar
    }

    const craftTagsPrivacy = privacy.craftTags || 'members'
    if (craftTagsPrivacy === 'public' || craftTagsPrivacy === 'members') {
      filtered.craftTags = candidate.craftTags
    }

    suggestions.push({
      member: filtered,
      matchingTags,
      matchCount: matchingTags.length
    })
  }

  // Sort by overlap count descending
  suggestions.sort((a, b) => b.matchCount - a.matchCount)

  return { suggestions }
})
