import { NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { db } from '@/lib/db'
import { visible } from '@/lib/scope'
import { saveImage, saveRawFile } from '@/lib/media'

export const runtime = 'nodejs'

const TARGETS = {
  thought: 'thoughtId',
  reminder: 'reminderId',
  checklist: 'checklistItemId',
} as const
type TargetType = keyof typeof TARGETS

// POST /api/attachments — attach files (images or anything else, e.g. PDFs)
// to a thought / reminder / checklist item.
// Multipart: targetType, targetId, files (one or more).
// Images get the WebP + thumbnail treatment; other files are stored raw.
export async function POST(req: Request) {
  const session = await getSession()
  if (!session) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })

  const form = await req.formData()
  const targetType = form.get('targetType') as string | null
  const targetId = (form.get('targetId') as string | null)?.trim()
  const files = form.getAll('files').filter((f): f is File => f instanceof File && f.size > 0)

  if (!targetType || !(targetType in TARGETS)) return NextResponse.json({ error: 'bad targetType' }, { status: 400 })
  if (!targetId) return NextResponse.json({ error: 'targetId required' }, { status: 400 })
  if (files.length === 0) return NextResponse.json({ error: 'no files' }, { status: 400 })

  // Verify the target exists.
  const exists =
    targetType === 'thought' ? await db.thought.findFirst({ where: { id: targetId, ...visible.thought(session.userId) }, select: { id: true } })
    : targetType === 'reminder' ? await db.reminder.findFirst({ where: { id: targetId, ...visible.reminder(session.userId) }, select: { id: true } })
    : await db.checklistItem.findFirst({ where: { id: targetId, ...visible.checklistItem(session.userId) }, select: { id: true } })
  if (!exists) return NextResponse.json({ error: 'target not found' }, { status: 404 })

  const fk = TARGETS[targetType as TargetType]
  const out: { id: string; name: string | null; mime: string | null; image: boolean }[] = []
  for (const f of files) {
    const buf = Buffer.from(await f.arrayBuffer())
    const mime = f.type || 'application/octet-stream'
    const isImage = mime.startsWith('image/')
    let data
    if (isImage) {
      const img = await saveImage(buf)
      data = { path: img.path, thumbPath: img.thumbPath, width: img.width, height: img.height, mime: 'image/webp', name: f.name || null }
    } else {
      const p = await saveRawFile(buf, f.name || 'file.bin')
      data = { path: p, mime, name: f.name || null }
    }
    const att = await db.attachment.create({ data: { ...data, [fk]: targetId }, select: { id: true, name: true, mime: true } })
    out.push({ id: att.id, name: att.name, mime: att.mime, image: isImage })
  }

  // Thoughts are cached client-side — move the version fingerprint.
  if (targetType === 'thought') {
    await db.thought.update({ where: { id: targetId }, data: { updatedAt: new Date() } }).catch(() => {})
  }

  return NextResponse.json({ attachments: out })
}
