import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
import {
  IsBoolean,
  IsIn,
  IsInt,
  IsNumber,
  IsOptional,
  IsString,
  Length,
  Max,
  Min,
} from 'class-validator';

const TIPOS = ['INGRESO', 'EGRESO'] as const;
const CATEGORIAS = [
  'SALARIO',
  'IPS',
  'HORA_EXTRA',
  'SUBSIDIO',
  'ANTICIPO',
  'DESCUENTO',
  'COMISION',
  'BONO',
  'OTRO',
] as const;
const APLICA_A = ['TODOS', 'MENSUAL', 'JORNAL', 'COMISION'] as const;

export class CreateConceptoDto {
  @ApiProperty()
  @IsString()
  @Length(1, 20)
  codigo!: string;

  @ApiProperty()
  @IsString()
  @Length(1, 100)
  nombre!: string;

  @ApiProperty({ enum: TIPOS })
  @IsString()
  @IsIn(TIPOS as unknown as string[])
  tipo!: (typeof TIPOS)[number];

  @ApiProperty({ enum: CATEGORIAS })
  @IsString()
  @IsIn(CATEGORIAS as unknown as string[])
  categoria!: (typeof CATEGORIAS)[number];

  @ApiPropertyOptional({ default: false })
  @IsOptional()
  @IsBoolean()
  afecta_base_ips?: boolean;

  @ApiPropertyOptional({ default: false })
  @IsOptional()
  @IsBoolean()
  afecta_base_aguinaldo?: boolean;

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  formula?: string;

  @ApiPropertyOptional({ default: false })
  @IsOptional()
  @IsBoolean()
  es_fijo?: boolean;

  @ApiPropertyOptional({ default: false })
  @IsOptional()
  @IsBoolean()
  es_porcentaje?: boolean;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(10)
  porcentaje?: number;

  @ApiPropertyOptional({ enum: APLICA_A, default: 'TODOS' })
  @IsOptional()
  @IsString()
  @IsIn(APLICA_A as unknown as string[])
  aplica_a?: (typeof APLICA_A)[number];

  @ApiPropertyOptional({ default: 0 })
  @IsOptional()
  @IsInt()
  orden_visualizacion?: number;

  @ApiPropertyOptional({ default: true })
  @IsOptional()
  @IsBoolean()
  activo?: boolean;
}

export class UpdateConceptoDto extends PartialType(CreateConceptoDto) {}

export class QueryConceptosDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  search?: string;

  @ApiPropertyOptional({ enum: TIPOS })
  @IsOptional()
  @IsString()
  @IsIn(TIPOS as unknown as string[])
  tipo?: string;

  @ApiPropertyOptional({ enum: CATEGORIAS })
  @IsOptional()
  @IsString()
  @IsIn(CATEGORIAS as unknown as string[])
  categoria?: string;
}
