import 'server-only'
import { db } from '@/lib/db'

// Owner resolution for the paths that have no session behind them: the Mac
// agent (bearer token, not a cookie) and system-generated activity.
//
// Session-backed routes must NOT use these — they scope to session.userId.

// The founding account: the oldest user. Owns everything that predates
// household accounts, and is the fallback wherever a single account has to
// stand in for "the household's own".
let foundingCache: string | null = null
export async function foundingOwnerId(): Promise<string> {
  if (foundingCache) return foundingCache
  const u = await db.user.findFirst({ orderBy: { createdAt: 'asc' }, select: { id: true } })
  if (!u) throw new Error('no users exist — cannot resolve the founding owner')
  foundingCache = u.id
  return u.id
}

// EventKit runs on one Mac under one iCloud account, so exactly one Steward
// account can have Apple mirroring. APPLE_OWNER_USER_ID names it explicitly;
// without it this is the founding account, which is the same thing until a
// second account exists.
//
// This is load-bearing: /api/agent/mirror full-reconciles and DELETES mirrored
// rows it no longer sees in EventKit. Scoped to the wrong owner — or left
// unscoped — it would reap another account's reminders. See PLAN.md §11.
export async function appleOwnerId(): Promise<string> {
  const configured = process.env.APPLE_OWNER_USER_ID?.trim()
  if (configured) return configured
  return foundingOwnerId()
}

// Split owner-stamped rows into one bucket per account, preserving the order
// the query returned them in. The organize pass is per-owner — one AI pass over
// one account's material — so every organize endpoint hands the agent buckets
// rather than a single blended list.
export function byOwner<T extends { ownerId: string }>(rows: T[]): { ownerId: string; rows: Omit<T, 'ownerId'>[] }[] {
  const buckets = new Map<string, Omit<T, 'ownerId'>[]>()
  for (const { ownerId, ...rest } of rows) {
    const bucket = buckets.get(ownerId)
    if (bucket) bucket.push(rest)
    else buckets.set(ownerId, [rest])
  }
  return [...buckets].map(([ownerId, rows]) => ({ ownerId, rows }))
}
