/**
 * Audit REST endpoints.
 *
 * POST   /audit          — fire-and-forget write
 * GET    /audit          — query audit logs (admin)
 * GET    /audit/stats    — aggregated action counts (admin)
 */

import type { FastifyInstance } from 'fastify';
import { getRequestProductId } from '../../lib/request-context.js';
import { BadRequestError } from '../../lib/errors.js';
import * as repo from './repository.js';
import { CreateAuditSchema, QueryAuditSchema, type AuditDoc } from './types.js';

export async function auditRoutes(app: FastifyInstance) {
  // Fire-and-forget write
  app.post('/audit', async (req, reply) => {
    const parsed = CreateAuditSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }
    const input = parsed.data;
    const productId = getRequestProductId(req);
    const doc: AuditDoc = {
      id: `aud_${crypto.randomUUID()}`,
      productId,
      ...input,
      timestamp: input.timestamp ?? new Date().toISOString(),
      createdAt: new Date().toISOString(),
    };
    // Fire-and-forget — don't await
    repo.create(doc).catch(err => app.log.error(err, 'Audit write failed'));
    reply.code(202);
    return { accepted: true };
  });

  // Query
  app.get('/audit', async req => {
    const query = req.query as Record<string, string>;
    const parsed = QueryAuditSchema.safeParse({
      userId: query.userId,
      action: query.action,
      category: query.category,
      days: query.days ? Number(query.days) : undefined,
      limit: query.limit ? Number(query.limit) : undefined,
      offset: query.offset ? Number(query.offset) : undefined,
    });
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }
    const productId = getRequestProductId(req);
    const records = await repo.query(parsed.data, productId);
    return { records, count: records.length };
  });

  // Stats
  app.get('/audit/stats', async req => {
    const { days = '30' } = req.query as { days?: string };
    const productId = getRequestProductId(req);
    const stats = await repo.getStats(Number(days), productId);
    return { stats, days: Number(days) };
  });
}
