import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'

const LOVE = 'love'

interface SwipeEntry {
  action?: string
  swipedAt?: number
}

/**
 * Creates a revealed date match when both partners have swiped LOVE on the
 * same date idea.
 *
 * Trigger: couples/{coupleId}/date_swipes/{dateIdeaId} (onWrite)
 *
 * The `date_matches` collection is server-write-only — Firestore rules deny all
 * client writes (`allow create, update, delete: if false`). This trigger is
 * therefore the single source of truth for match creation. The client only
 * records swipes and observes `date_matches` for the result.
 *
 * Idempotency: the match document id is the date idea id and creation runs in a
 * transaction, so repeated swipes on the same idea and concurrent invocations
 * never produce a duplicate match.
 */
export const createDateMatchOnMutualLove = functions.firestore
  .document('couples/{coupleId}/date_swipes/{dateIdeaId}')
  .onWrite(async (change, context) => {
    const after = change.after.data()
    if (!after) return // swipe document was deleted

    const actions = (after.actions ?? {}) as Record<string, SwipeEntry>
    const lovedBy = Object.entries(actions)
      .filter(([, entry]) => entry?.action === LOVE)
      .map(([uid]) => uid)
      .sort()

    // A match needs both partners to have loved the same idea.
    if (lovedBy.length < 2) return

    const { coupleId, dateIdeaId } = context.params as {
      coupleId: string
      dateIdeaId: string
    }

    const db = admin.firestore()
    const matchRef = db
      .collection('couples')
      .doc(coupleId)
      .collection('date_matches')
      .doc(dateIdeaId)

    await db.runTransaction(async (tx) => {
      const existing = await tx.get(matchRef)
      if (existing.exists) return // already matched — no-op
      tx.set(matchRef, {
        dateIdeaId,
        matchedBy: lovedBy,
        revealedAt: admin.firestore.FieldValue.serverTimestamp(),
      })
    })
  })
