// Routes Web Push (P4). Toutes sous l'auth globale (preValidation) : aucune route publique.
// L'abonnement est lié au token authentifié (req.authContext.tokenId).
import type { FastifyInstance } from 'fastify';
import type { PushSubscribeRequest, PushUnsubscribeRequest, VapidKeyResponse } from '@arboretum/shared';
import type { PushService } from '../core/push-service.js';
import type { Db } from '../db/index.js';
import { recordAudit } from '../core/audit-log.js';

export function registerPushRoutes(app: FastifyInstance, push: PushService, db: Db): void {
  app.get('/api/v1/push/vapid-public-key', async (): Promise<VapidKeyResponse> => ({ key: push.publicKey() }));

  app.post('/api/v1/push/subscribe', async (req, reply) => {
    const body = req.body as Partial<PushSubscribeRequest> | null;
    if (!body || typeof body.endpoint !== 'string' || !body.keys || typeof body.keys.p256dh !== 'string' || typeof body.keys.auth !== 'string') {
      return reply.status(400).send({ error: { code: 'BAD_REQUEST', message: 'endpoint and keys{p256dh,auth} are required' } });
    }
    // garanti non-null : la route est protégée par le preValidation global.
    const tokenId = req.authContext!.tokenId;
    push.subscribe(tokenId, { endpoint: body.endpoint, keys: { p256dh: body.keys.p256dh, auth: body.keys.auth } }, req.headers['user-agent'] ?? null);
    recordAudit(db, { actor: tokenId, action: 'push.subscribe' });
    return reply.status(201).send({ ok: true });
  });

  app.post('/api/v1/push/unsubscribe', async (req, reply) => {
    const body = req.body as Partial<PushUnsubscribeRequest> | null;
    if (!body || typeof body.endpoint !== 'string') {
      return reply.status(400).send({ error: { code: 'BAD_REQUEST', message: 'endpoint is required' } });
    }
    push.unsubscribe(body.endpoint);
    recordAudit(db, { actor: req.authContext?.tokenId ?? 'unknown', action: 'push.unsubscribe' });
    return reply.send({ ok: true });
  });

  // Notification de test (diagnostic mobile) : pousse vers tous les abonnements de l'utilisateur.
  app.post('/api/v1/push/test', async (_req, reply) => {
    await push.notify({ sessionId: 'test', title: 'Arboretum', body: 'Push notifications are working.', kind: null, url: '/' });
    return reply.send({ ok: true });
  });
}
