import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSessionUser } from '@/lib/auth'
import { verifyPreferenceToken } from '@/lib/email/tokens'
import { loadPreferences, resubscribeUpdates, savePreferences, unsubscribeUpdates } from '@/lib/email/send'
import { EMAIL_CATEGORIES } from '@/lib/domain/email-policy'

/**
 * Email preferences (2026-09-22). Signed-in: the account's own categories.
 * With a token (from an email link): the preference center / unsubscribe for
 * that address, no sign-in needed. Required categories cannot be turned off.
 */
const prefFields = EMAIL_CATEGORIES.filter((c) => c.preferenceField).map((c) => c.preferenceField as string)
const patchSchema = z.object(Object.fromEntries(prefFields.map((f) => [f, z.boolean().optional()])) as Record<string, z.ZodOptional<z.ZodBoolean>>)
const schema = z.discriminatedUnion('op', [
  z.object({ op: z.literal('save'), token: z.string().optional(), prefs: patchSchema }),
  z.object({ op: z.literal('unsubscribe_updates'), token: z.string().optional() }),
  z.object({ op: z.literal('resubscribe_updates'), token: z.string().optional() }),
])

async function identify(token?: string) {
  if (token) {
    const t = await verifyPreferenceToken(token)
    return t ? { email: t.email, userId: t.userId, label: `preference center (${t.email})` } : null
  }
  const user = await getSessionUser()
  return user ? { email: user.email, userId: user.id, label: user.name || user.email } : null
}

export async function GET() {
  const user = await getSessionUser()
  if (!user) return NextResponse.json({ error: 'Sign in first.' }, { status: 401 })
  return NextResponse.json(await loadPreferences(user.id))
}

export async function POST(req: NextRequest) {
  const parsed = schema.safeParse(await req.json().catch(() => ({})))
  if (!parsed.success) return NextResponse.json({ error: 'Invalid request.' }, { status: 400 })
  const input = parsed.data
  const who = await identify(input.token)
  if (!who) return NextResponse.json({ error: 'This link is not valid. Sign in to manage your email preferences.' }, { status: 401 })
  if (input.op === 'unsubscribe_updates') {
    const r = await unsubscribeUpdates({ email: who.email, userId: who.userId }, who.label)
    return r.ok ? NextResponse.json({ ok: true }) : NextResponse.json({ error: r.error }, { status: 400 })
  }
  if (input.op === 'resubscribe_updates') {
    const r = await resubscribeUpdates({ email: who.email, userId: who.userId }, { product_updates: true, newsletter: true, marketing_campaigns: true, pilot_opportunities: true, broker_opportunities: true, carrier_opportunities: true }, who.label)
    return r.ok ? NextResponse.json({ ok: true }) : NextResponse.json({ error: r.error }, { status: 400 })
  }
  if (!who.userId) return NextResponse.json({ error: 'Category preferences need a HeavyHaul Agent account. You can still unsubscribe from updates.' }, { status: 400 })
  const r = await savePreferences(who.userId, input.prefs, who.label)
  if (!r.ok) return NextResponse.json({ error: r.error }, { status: 400 })
  // Turning any updates category back on lifts a self-unsubscribe suppression.
  if (Object.values(input.prefs).some(Boolean)) await resubscribeUpdates({ email: who.email, userId: who.userId }, {}, who.label)
  return NextResponse.json({ ok: true })
}
