import { ApiProperty } from '@nestjs/swagger';
import { BaseFilterEntity } from '../../domain/entities/base-filter.entity';
import { Transform } from 'class-transformer';
import {
  IsArray,
  IsEnum,
  IsNumber,
  IsString,
  ValidateIf,
} from 'class-validator';
import { ORDER_TYPE, STATUS } from 'src/core/strings/constants/base.constants';

export class BaseFilterDto implements BaseFilterEntity {
  @ApiProperty({ type: Number, required: false, default: 1 })
  @Transform((body) => Number(body.value))
  @ValidateIf((body) => body.page)
  @IsNumber()
  page = 1;

  @ApiProperty({ type: Number, required: false, default: 10 })
  @Transform((body) => Number(body.value))
  @ValidateIf((body) => body.limit)
  @IsNumber()
  limit = 10;

  @ApiProperty({ type: String, required: false })
  q: string;

  @ApiProperty({ type: ['string'], required: false })
  @Transform((body) => {
    return Array.isArray(body.value) ? body.value : [body.value];
  })
  names: string[];

  @ApiProperty({ type: String, required: false })
  order_by: string;

  @ApiProperty({
    type: 'string',
    required: false,
    description: `Select ("${ORDER_TYPE.ASC}", "${ORDER_TYPE.DESC}")`,
  })
  @ValidateIf((body) => body.order_type)
  @IsEnum(ORDER_TYPE, {
    message: `order_type must be a valid enum ${JSON.stringify(
      Object.values(ORDER_TYPE),
    )}`,
  })
  order_type: ORDER_TYPE;

  @ApiProperty({
    type: ['string'],
    required: false,
    description: `Select ["${STATUS.ACTIVE}"]`,
  })
  @Transform((body) => {
    return Array.isArray(body.value) ? body.value : [body.value];
  })
  @ValidateIf((body) => {
    return body.status;
  })
  @IsArray()
  @IsString({ each: true })
  statuses: STATUS[];

  @ApiProperty({ type: [String], required: false })
  @Transform((body) => {
    return Array.isArray(body.value) ? body.value : [body.value];
  })
  @ValidateIf((body) => body.created_ids)
  @IsArray()
  @IsString({ each: true })
  created_ids: string[];

  @ApiProperty({ type: 'integer', required: false })
  @ValidateIf((body) => body.created_from)
  created_from: number;

  @ApiProperty({ type: 'integer', required: false })
  @ValidateIf((body) => body.created_to)
  created_to: number;

  @ApiProperty({ type: [String], required: false })
  @Transform((body) => {
    return Array.isArray(body.value) ? body.value : [body.value];
  })
  @ValidateIf((body) => body.updated_ids)
  @IsArray()
  @IsString({ each: true })
  updated_ids: string[];

  @ApiProperty({ type: 'integer', required: false })
  @Transform((body) => {
    return typeof body.value == 'string' ? Number(body.value) : body.value;
  })
  @ValidateIf((body) => body.updated_from)
  updated_from: number;

  @ApiProperty({ type: 'integer', required: false })
  @Transform((body) => {
    return typeof body.value == 'string' ? Number(body.value) : body.value;
  })
  @ValidateIf((body) => body.updated_to)
  updated_to: number;

  @ApiProperty({ type: [String], required: false })
  @Transform((body) => {
    return Array.isArray(body.value) ? body.value : [body.value];
  })
  @ValidateIf((body) => body.entity_ids)
  @IsArray()
  @IsString({ each: true })
  entity_ids: string[];
}
