import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSessionUser } from '@/lib/auth'
import { publicOrigin } from '@/lib/app-url'
import { clientIp } from '@/lib/security/rate-limit'
import { canManageAccess, isDelegatable, SURFACE_KEYS, type SurfaceKey } from '@/lib/domain/moderator-access'
import { grantSurface, listAccessLog, listGrants, moderatorAccessAvailable, reinviteSurface, revokeSurface } from '@/lib/data/moderator-access'

/**
 * Who may open one moderator page (Nash, 2026-09-23). Only the platform admin
 * reads or changes this — "he cannot invite anyone else, only the admin can".
 */
const surfaceEnum = z.enum(SURFACE_KEYS as [SurfaceKey, ...SurfaceKey[]])
const schema = z.discriminatedUnion('op', [
  z.object({ op: z.literal('grant'), surface: surfaceEnum, email: z.string().trim().max(200), name: z.string().trim().max(120).optional(), note: z.string().trim().max(400).optional() }),
  z.object({ op: z.literal('revoke'), grant_id: z.string().uuid() }),
  z.object({ op: z.literal('reinvite'), grant_id: z.string().uuid() }),
])

export async function GET(req: NextRequest) {
  const user = await getSessionUser()
  if (!user) return NextResponse.json({ error: 'Sign in first.' }, { status: 401 })
  if (!canManageAccess(user)) return NextResponse.json({ error: 'Only the HeavyHaul Agent admin can see who has access.' }, { status: 403 })
  const surface = req.nextUrl.searchParams.get('surface') ?? ''
  if (!isDelegatable(surface)) return NextResponse.json({ error: 'That page cannot be delegated.' }, { status: 400 })
  if (!(await moderatorAccessAvailable())) return NextResponse.json({ error: 'Moderator access needs database migration 0032.' }, { status: 503 })
  const [grants, log] = await Promise.all([listGrants(surface as SurfaceKey), listAccessLog(surface as SurfaceKey)])
  return NextResponse.json({ grants, log })
}

export async function POST(req: NextRequest) {
  const user = await getSessionUser()
  if (!user) return NextResponse.json({ error: 'Sign in first.' }, { status: 401 })
  if (!canManageAccess(user)) return NextResponse.json({ error: 'Only the HeavyHaul Agent admin can grant or revoke page access.' }, { status: 403 })
  const parsed = schema.safeParse(await req.json().catch(() => ({})))
  if (!parsed.success) return NextResponse.json({ error: 'Check the request and try again.' }, { status: 400 })
  if (!(await moderatorAccessAvailable())) return NextResponse.json({ error: 'Moderator access needs database migration 0032.' }, { status: 503 })
  const input = parsed.data
  const actor = { id: user.id, label: user.name || user.email, email: user.email, ip: clientIp(req.headers) }
  const origin = publicOrigin(req)

  if (input.op === 'grant') {
    const r = await grantSurface({ surface: input.surface, email: input.email, name: input.name ?? null, note: input.note ?? null, actor, origin })
    return r.ok ? NextResponse.json({ ok: true, grant: r.grant, email_status: r.emailStatus }) : NextResponse.json({ error: r.error }, { status: 400 })
  }
  if (input.op === 'reinvite') {
    const r = await reinviteSurface({ grantId: input.grant_id, actor, origin })
    return r.ok ? NextResponse.json({ ok: true, email_status: r.emailStatus }) : NextResponse.json({ error: r.error }, { status: 400 })
  }
  const r = await revokeSurface({ grantId: input.grant_id, actor })
  return r.ok ? NextResponse.json({ ok: true }) : NextResponse.json({ error: r.error }, { status: 400 })
}
