import { NextResponse } from 'next/server'
import { z } from 'zod'
import { checkAgentAuth } from '@/lib/agent-auth'
import { pushToUser } from '@/lib/push'
import { sendTelegram } from '@/lib/telegram'
import { foundingOwnerId } from '@/lib/owner'

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

// POST /api/notify — a one-off push to the household's own devices.
// Auth: agent bearer token (the same AGENT_TOKEN as /api/monitor/ingest).
//
// For something a Mac-side watcher notices and wants on the phone NOW — e.g.
// the solar-shed door left open 15 minutes — as opposed to a scheduled reminder
// (those are rows the app fires on its own clock). Web Push is the primary
// channel: it IS the Steward app's own notification. If no live subscription
// takes it, Telegram is the fallback so the message still lands. Best-effort and
// strictly additive — it can notify, never change state.
const BodySchema = z.object({
  title: z.string().min(1).max(120),
  body: z.string().min(1).max(500),
  // Opened when the web-push notification is tapped (relative = inside the PWA).
  url: z.string().max(500).optional(),
  // Collapses an earlier notification with the same tag instead of stacking.
  tag: z.string().max(64).optional(),
  // Also send Telegram even when web push succeeded (default: Telegram only as a
  // fallback when no web-push subscription is live).
  telegram: z.boolean().optional(),
})

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

  let data: z.infer<typeof BodySchema>
  try {
    data = BodySchema.parse(await req.json())
  } catch (e) {
    return NextResponse.json({ error: 'Invalid body', detail: (e as Error).message }, { status: 400 })
  }

  const ownerId = await foundingOwnerId()
  const sent = await pushToUser(ownerId, {
    title: data.title,
    body: data.body,
    url: data.url,
    tag: data.tag,
  })

  // Fall back to Telegram when no web-push device took it (or when asked for
  // both). sendTelegram is best-effort and never throws.
  let telegram = false
  if (data.telegram || sent === 0) {
    telegram = await sendTelegram(`${data.title}\n${data.body}`)
  }

  return NextResponse.json({ ok: sent > 0 || telegram, sent, telegram })
}
