/**
 * Configurable request context helpers for Fastify product backends.
 *
 * Factory function creates getRequestProductId() and getUserId() bound to
 * the provided product ID, eliminating hardcoded product IDs in each repo.
 */
import type { FastifyRequest } from 'fastify';
import { BadRequestError } from '@bytelyst/errors';
import type { RequestContextOptions } from './types.js';

export function createRequestContext(opts: RequestContextOptions) {
  const { productId } = opts;

  /**
   * Extract productId from request. Validates against this backend's product ID.
   * Falls back to the configured productId since this is a product-specific backend.
   */
  function getRequestProductId(req: FastifyRequest): string {
    // 1. From JWT
    const jwtPid = req.jwtPayload?.productId;
    if (jwtPid && jwtPid !== productId) {
      throw new BadRequestError(`Invalid productId: expected ${productId}, got ${jwtPid}`);
    }

    // 2. From header
    const header = req.headers['x-product-id'];
    if (typeof header === 'string' && header.length > 0 && header !== productId) {
      throw new BadRequestError(`Invalid productId: expected ${productId}, got ${header}`);
    }

    return productId;
  }

  /**
   * Extract userId from the JWT payload on the request.
   * Throws BadRequestError if no authenticated user is found.
   */
  function getUserId(req: FastifyRequest): string {
    const sub = req.jwtPayload?.sub;
    if (!sub) {
      throw new BadRequestError('Missing userId — request must be authenticated');
    }
    return sub;
  }

  return { getRequestProductId, getUserId };
}
