import {
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
  Logger,
} from "@nestjs/common";

/**
 * TenantBodyGuard
 *
 * Prevents privilege escalation by ensuring no request body contains a
 * `companyId` field that differs from the authenticated tenant's companyId.
 * This blocks attackers from injecting a different company's ID to access
 * or modify data across tenants.
 */
@Injectable()
export class TenantBodyGuard implements CanActivate {
  private readonly logger = new Logger("TenantBodyGuard");

  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest<{
      tenantId?: string;
      ip: string;
      url: string;
      method: string;
      body?: Record<string, unknown>;
      headers: Record<string, string>;
    }>();

    const tenantId = request.tenantId;
    const bodyCompanyId = request.body?.companyId as string | undefined;

    if (bodyCompanyId && tenantId && bodyCompanyId !== tenantId) {
      const ip =
        request.headers["x-forwarded-for"]?.split(",")[0]?.trim() ||
        request.ip;
      this.logger.warn(
        `[TENANT_INJECTION] IP: ${ip} | URL: ${request.method} ${request.url} | ` +
          `Tentou companyId="${bodyCompanyId}" mas é tenant="${tenantId}"`,
      );
      throw new ForbiddenException(
        "Acesso negado: operação em empresa não autorizada.",
      );
    }

    return true;
  }
}
