/**
 * POST /api/chat/image  (JSON)
 *   { to, clientMsgId, fromName, thumbUrl, fullUrl, width, height }
 *
 * Records an image message. The image itself is uploaded by the CLIENT to Strapi (public media, the
 * same path the mobile pages use) — this route only stores the resulting Strapi URLs on a normal chat
 * message (meta { kind:'image', thumbUrl, fullUrl }) and fans it out over the socket + push. Nothing is
 * stored in chat.db beyond the message row, so the DB stays small. Gated to staff; 404 when disabled.
 */

import { gateFromEvent, isStaffUser } from '../../utils/chatAccess'
import { insertMessage } from '../../utils/chatDb'
import { sendToUser, isConnected } from '../../utils/chatPresence'
import { sendPushToUser, buildChatMessagePayload } from '../../utils/pushNotifier'
import { sendFcmToUser } from '../../utils/fcmNotifier'

const IMAGE_LABEL = '📷 Bild'

export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig()
  if (config.chatEnabled !== true) { setResponseStatus(event, 404); return { error: 'chat disabled' } }

  let userId: number, token: string
  try {
    ({ userId, token } = await gateFromEvent(event))
  } catch (err: any) {
    setResponseStatus(event, err?.statusCode || 403)
    return { error: 'forbidden' }
  }

  const body = await readBody(event)
  const to = Number(body?.to)
  const clientMsgId = String(body?.clientMsgId || '')
  const fromName = String(body?.fromName || '')
  const thumbUrl = String(body?.thumbUrl || '')
  const fullUrl = String(body?.fullUrl || thumbUrl)
  const width = Number(body?.width) || 0
  const height = Number(body?.height) || 0

  if (!to || to === userId) { setResponseStatus(event, 400); return { error: 'bad recipient' } }
  // Only accept our own Strapi file URLs (defends the <img>/<a> sinks against arbitrary/`javascript:` URLs).
  if (!/^https?:\/\/.+\/files-api\//.test(thumbUrl)) { setResponseStatus(event, 400); return { error: 'invalid image url' } }

  // Recipient must be staff (mirror the WS message guard). Only reject on a hard "no".
  if (!isConnected(to)) {
    const staff = await isStaffUser(to, token)
    if (staff === false) { setResponseStatus(event, 403); return { error: 'recipient not allowed' } }
  }

  const meta: any = { kind: 'image', thumbUrl, fullUrl, width, height }
  const createdAt = Date.now()
  const saved = insertMessage({
    senderUserId: userId,
    recipientUserId: to,
    body: IMAGE_LABEL,
    createdAt,
    clientMsgId: clientMsgId || null,
    meta
  })
  const msg = saved ?? {
    id: null, senderUserId: userId, recipientUserId: to, body: IMAGE_LABEL,
    createdAt, readAt: null, clientMsgId: clientMsgId || null, meta
  }

  const out = { type: 'message', message: msg }
  sendToUser(to, out)
  sendToUser(userId, out)

  // Native FCM to ALL the recipient's devices regardless of presence (see voice route rationale).
  sendFcmToUser(to, {
    title: fromName || 'Neue Nachricht',
    body: IMAGE_LABEL,
    data: { senderUserId: String(userId), url: `/chat?chat=${userId}` },
  }).catch((e: any) => console.error('[ChatImage] FCM failed:', e?.message))

  // Web push (browsers/PWA) stays offline-only.
  if (!isConnected(to)) {
    const payload = buildChatMessagePayload(fromName || '', IMAGE_LABEL, userId)
    sendPushToUser(to, payload).catch((e: any) => console.error('[ChatImage] offline push failed:', e?.message))
  }

  return { status: 200, message: msg }
})
