import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { checkAgentAuth, checkCallbackSecret } from '@/lib/agent-auth'
import { logActivity } from '@/lib/activity'
import { byOwner, foundingOwnerId } from '@/lib/owner'

export const runtime = 'nodejs'

// GET /api/agent/thoughts — non-archived thoughts for the organize pass,
// bucketed by account.
//
// The pass runs once per bucket. Blending accounts would be wrong twice over:
// the themes a thought gets grouped under would be drawn from material its
// owner never wrote, and the per-topic summary — which is shown back to the
// owner — would synthesize somebody else's thinking into it.
export async function GET(req: Request) {
  if (!checkAgentAuth(req)) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })
  const thoughts = await db.thought.findMany({
    where: { archived: false },
    orderBy: { createdAt: 'asc' },
    select: { id: true, body: true, tags: true, ownerId: true },
  })
  return NextResponse.json({
    owners: byOwner(thoughts).map(g => ({ ownerId: g.ownerId, thoughts: g.rows })),
  })
}

// POST /api/agent/thoughts — apply the organize results for ONE account.
// Body: { ownerId, items: [{ id, topic, tags, duplicateOf }], topics: [{ name, summary }] }
export async function POST(req: Request) {
  if (!checkAgentAuth(req)) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })
  if (!checkCallbackSecret(req)) return NextResponse.json({ error: 'bad callback secret' }, { status: 403 })

  const body = await req.json().catch(() => null)
  const items: { id?: string; topic?: string; tags?: string[]; duplicateOf?: string }[] =
    Array.isArray(body?.items) ? body.items : []
  const topics: { name?: string; summary?: string }[] = Array.isArray(body?.topics) ? body.topics : []

  // Which account this pass was over. Omitted means the founding account —
  // the pre-household behaviour, kept so an agent that has not been redeployed
  // yet still organizes Eric's thoughts rather than erroring.
  const requested = typeof body?.ownerId === 'string' ? body.ownerId.trim() : ''
  if (requested && !(await db.user.findUnique({ where: { id: requested }, select: { id: true } }))) {
    return NextResponse.json({ error: 'unknown ownerId' }, { status: 400 })
  }
  const ownerId = requested || (await foundingOwnerId())

  // Every write is pinned to that owner. The ids come back from an LLM that
  // was shown one account's thoughts, so a crossed id is a bug rather than an
  // attack — but it would silently retopic someone else's thought, and this
  // makes that impossible rather than unlikely.
  let updated = 0
  for (const it of items) {
    if (!it.id) continue
    const res = await db.thought.updateMany({
      where: { id: it.id, ownerId },
      data: {
        topic: it.topic || null,
        tags: Array.isArray(it.tags) ? it.tags.filter(x => typeof x === 'string') : undefined,
        duplicateOf: it.duplicateOf || null,
      },
    })
    updated += res.count
  }

  // Synthesis: upsert per-topic summaries. Topic names are unique per owner, so
  // two accounts may each have a "Quail" with their own summary.
  for (const t of topics) {
    if (!t.name) continue
    await db.topic.upsert({
      where: { ownerId_name: { ownerId, name: t.name } },
      update: { summary: t.summary || null },
      create: { ownerId, name: t.name, summary: t.summary || null },
    })
  }

  logActivity(ownerId, 'organize.thoughts', `Organize pass: ${updated} thoughts across ${topics.length} topics`)
  return NextResponse.json({ ok: true, updated, topics: topics.length })
}
