import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class TrimPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    if (value === null || value === undefined) {
      return value;
    }

    // parse string and trim
    if (typeof value === 'string') {
      return value.trim();
    }

    // parse object and trim
    if (typeof value === 'object' && !Array.isArray(value)) {
      return this.trimObject(value);
    }

    // parse array and trim
    if (Array.isArray(value)) {
      return value.map((item) =>
        typeof item === 'string'
          ? item.trim()
          : this.transform(item, { ...metadata }),
      );
    }
    return value;
  }

  private trimObject(obj: any): any {
    Object.keys(obj).forEach((key) => {
      if (typeof obj[key] === 'string') {
        obj[key] = obj[key].trim();
      } else if (
        typeof obj[key] === 'object' &&
        !Array.isArray(obj[key]) &&
        obj[key] !== null
      ) {
        obj[key] = this.trimObject(obj[key]);
      } else if (Array.isArray(obj[key])) {
        obj[key] = obj[key].map((item) =>
          typeof item === 'string'
            ? item.trim()
            : this.transform(item, { type: 'custom' }),
        );
      }
    });
    return obj;
  }
}
