import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { checkAgentAuth } from '@/lib/agent-auth'
import { foundingOwnerId } from '@/lib/owner'
import { pushToUser } from '@/lib/push'

export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'

// POST — the loop raising its hand. GET — what it still owes a reply to.
//
// Both agent-token, both called from the quail-loop tick on the mini.

export async function POST(req: Request) {
  if (!checkAgentAuth(req)) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })

  const b = await req.json().catch(() => ({}))
  const threadId = String(b.threadId || '').slice(0, 120)
  const question = String(b.question || '').trim().slice(0, 1500)
  if (!threadId) return NextResponse.json({ error: 'threadId is required' }, { status: 400 })
  if (!question) return NextResponse.json({ error: 'question is required — what could you not decide?' }, { status: 400 })

  // One open question per thread, forever. The loop is a fresh session every
  // twenty minutes with no memory of the last one, so without this the same
  // buyer would pile up a new card every tick — which is exactly the failure
  // the old "Decision needed" email had to dedup against by searching its own
  // sent mail. Here the uniqueness is just a query.
  const open = await db.quailDecision.findFirst({
    where: { threadId, state: { in: ['OPEN', 'ANSWERED'] } },
    select: { id: true, state: true },
  })
  if (open) return NextResponse.json({ ok: true, id: open.id, alreadyOpen: true, state: open.state })

  const row = await db.quailDecision.create({
    data: {
      threadId,
      question,
      buyerName: b.buyerName ? String(b.buyerName).slice(0, 120) : null,
      subject: b.subject ? String(b.subject).slice(0, 200) : null,
      threadUrl: b.threadUrl ? String(b.threadUrl).slice(0, 400) : null,
      context: b.context ? String(b.context).slice(0, 2000) : null,
      source: b.source === 'support' ? 'support' : 'craigslist',
    },
  })

  // Tell him on his phone. Deliberately AFTER the dedup check above, so this
  // fires once per thread and not every twenty minutes for as long as the
  // buyer waits — a notification that repeats itself is one you swipe away
  // without reading, and then the real one goes with it.
  //
  // No quiet-hours guard here on purpose: the loop itself only runs 07:00–23:00
  // (activeHours in jobs/quail-loop/config.json), so there is no tick at 3am
  // that could raise one. If that schedule ever widens, this needs a guard.
  //
  // Never throws, and the notification is not the point of the request — the
  // card on /health is. A dead push service must not fail the loop's POST and
  // lose the question with it.
  try {
    const title = row.buyerName ? `${row.buyerName} needs an answer` : 'A quail buyer needs an answer'
    await pushToUser(await foundingOwnerId(), {
      title,
      // The question itself, not "you have 1 notification". He should be able
      // to decide whether to get up from the table without opening anything.
      body: question.slice(0, 180),
      url: '/health',
      // One per thread: a second question about the same buyer replaces the
      // first rather than stacking beside it.
      tag: `quail-${threadId}`,
    })
  } catch (e) {
    console.error('[quail decision] push failed:', (e as Error)?.message)
  }

  return NextResponse.json({ ok: true, id: row.id })
}

// GET ?state=ANSWERED — what Eric has ruled on and the loop has not sent yet.
export async function GET(req: Request) {
  if (!checkAgentAuth(req)) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })

  const state = new URL(req.url).searchParams.get('state') === 'OPEN' ? 'OPEN' : 'ANSWERED'
  const rows = await db.quailDecision.findMany({
    where: { state },
    orderBy: { createdAt: 'asc' },
    take: 10,
  })
  return NextResponse.json({
    decisions: rows.map(r => ({
      id: r.id, threadId: r.threadId, buyerName: r.buyerName, subject: r.subject,
      threadUrl: r.threadUrl, question: r.question, context: r.context, source: r.source,
      answer: r.answer, hasAudio: Boolean(r.answerAudio), answeredAt: r.answeredAt,
    })),
  })
}
