import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from "@nestjs/common";
import { Observable } from "rxjs";

/**
 * Strips HTML/script tags from all string values in the request body.
 * Applied globally to prevent stored XSS via API inputs.
 */
@Injectable()
export class SanitizeInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
    const request = context.switchToHttp().getRequest();

    if (request.body && typeof request.body === "object") {
      request.body = this.sanitize(request.body);
    }

    return next.handle();
  }

  private sanitize(value: unknown): unknown {
    if (typeof value === "string") {
      return this.stripTags(value);
    }

    if (Array.isArray(value)) {
      return value.map((item) => this.sanitize(item));
    }

    if (value !== null && typeof value === "object") {
      const sanitized: Record<string, unknown> = {};
      for (const [key, val] of Object.entries(value)) {
        sanitized[key] = this.sanitize(val);
      }
      return sanitized;
    }

    return value;
  }

  private stripTags(input: string): string {
    return input.replace(/<[^>]*>/g, "");
  }
}
