import { FastifyInstance } from 'fastify';
import { authenticate } from '../middleware/auth';
import { signMediaPath } from '../../../utils/signed-url';

/**
 * POST /api/media/sign — body: { path: string, ttlSeconds?: number }
 *
 * Returns short-lived HMAC-signed query params for embedding the given path
 * in an `<img src>` / `<video src>` / SSE URL. Requires header auth (the
 * caller must have a valid Bearer JWT). The returned params are path-scoped
 * and expire in `ttlSeconds` (capped at 900s / 15 min).
 *
 * Replaces the legacy pattern of putting the JWT itself in `?token=` on
 * 2026-04-12 — see utils/signed-url.ts for background.
 */
interface SignRequestBody { path?: string; ttlSeconds?: number }

export async function signRoutes(fastify: FastifyInstance) {
  fastify.post<{ Body: SignRequestBody }>(
    '/sign',
    { preHandler: authenticate },
    async (request, reply) => {
      const { path, ttlSeconds } = request.body ?? {};
      if (typeof path !== 'string' || path.length === 0 || path.length > 512) {
        return reply.status(400).send({ error: 'Invalid path', code: 'INVALID_PATH' });
      }
      // Reject anything that's not a path on our own API — prevents signed-URL
      // generation for arbitrary URLs (would otherwise be a blind-signer oracle).
      if (!path.startsWith('/api/')) {
        return reply.status(400).send({ error: 'Path must start with /api/', code: 'INVALID_PATH' });
      }
      const ttl = Math.min(Math.max(Number(ttlSeconds) || 300, 30), 900);
      const userId = request.user!.id;
      const signed = signMediaPath(path, userId, ttl);
      const separator = path.includes('?') ? '&' : '?';
      const query = `sig=${signed.sig}&exp=${signed.exp}&uid=${signed.uid}`;
      return reply.send({
        url: `${path}${separator}${query}`,
        ...signed,
        expiresAt: new Date(Number(signed.exp) * 1000).toISOString(),
      });
    }
  );
}
