import type { FastifyRequest } from 'fastify';
import type { FastifyApp } from './types.js';

interface JwtCarrier {
  jwtPayload?: unknown;
}

export interface OptionalJwtContextOptions<TPayload> {
  onError?: (error: unknown, request: FastifyRequest) => Promise<void> | void;
  verifyToken: (token: string, request: FastifyRequest) => Promise<TPayload> | TPayload;
}

export async function registerOptionalJwtContext<TPayload>(
  app: FastifyApp,
  options: OptionalJwtContextOptions<TPayload>
): Promise<void> {
  const { verifyToken, onError } = options;

  app.addHook('onRequest', async req => {
    const auth = req.headers.authorization;
    if (!auth?.startsWith('Bearer ')) return;

    try {
      const payload = await verifyToken(auth.slice(7), req);
      (req as FastifyRequest & JwtCarrier).jwtPayload = payload;
    } catch (error) {
      if (onError) {
        await onError(error, req);
      }
    }
  });
}
