import { ApiPropertyOptional } from '@nestjs/swagger';
import { inm_indice_tipo } from '@prisma/client';
import {
  IsBoolean,
  IsEnum,
  IsIn,
  IsInt,
  IsNumber,
  IsOptional,
  IsString,
  IsUUID,
  Max,
  MaxLength,
  Min,
} from 'class-validator';

export class UpdateParametrosDto {
  @ApiPropertyOptional({ example: 7, description: 'Días que una reserva bloquea la unidad antes de vencer.' })
  @IsOptional()
  @IsInt()
  @Min(1, { message: 'Los días de reserva no pueden ser menor que 1' })
  @Max(365, { message: 'Los días de reserva no pueden ser mayor que 365' })
  dias_reserva?: number;

  @ApiPropertyOptional({ example: 10, description: 'Seña mínima, en % del precio.' })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 2 })
  @Min(0, { message: 'La seña mínima (%) no puede ser menor que 0' })
  @Max(100, { message: 'La seña mínima (%) no puede ser mayor que 100' })
  pct_sena_min?: number;

  @ApiPropertyOptional({
    example: 25,
    description: 'Porcentaje pagado a partir del cual se avisa que el comprador puede exigir escritura (lotes).',
  })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 2 })
  @Min(0, { message: 'El aviso de escritura (%) no puede ser menor que 0' })
  @Max(100, { message: 'El aviso de escritura (%) no puede ser mayor que 100' })
  pct_aviso_escritura?: number;

  @ApiPropertyOptional({ example: 3, description: 'Cuotas vencidas que disparan la alerta de rescisión.' })
  @IsOptional()
  @IsInt()
  @Min(1, { message: 'Las cuotas para alerta de rescisión no pueden ser menor que 1' })
  @Max(120, { message: 'Las cuotas para alerta de rescisión no pueden ser mayor que 120' })
  cuotas_alerta_rescision?: number;

  @ApiPropertyOptional({
    example: 30,
    description: 'Parte del precio gravada con IVA (afectación 4). Se copia a cada operación al firmar.',
  })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 2 })
  @Min(1, { message: 'La base gravada (%) no puede ser menor que 1' })
  @Max(99, { message: 'La base gravada (%) no puede ser mayor que 99' })
  proporcion_gravada?: number;

  @ApiPropertyOptional({ example: 5, enum: [5, 10] })
  @IsOptional()
  @IsIn([5, 10], { message: 'La tasa de IVA es 5 o 10' })
  tasa_iva?: number;

  @ApiPropertyOptional({ enum: inm_indice_tipo, example: inm_indice_tipo.IPC_BCP })
  @IsOptional()
  @IsEnum(inm_indice_tipo)
  indice_ajuste?: inm_indice_tipo;

  @ApiPropertyOptional({ description: 'Producto de servicio con el que se factura cada cuota' })
  @IsOptional()
  @IsUUID()
  producto_cuota_id?: string | null;

  @ApiPropertyOptional({ description: 'Timbrado / punto de expedición por defecto para las facturas de cuotas' })
  @IsOptional()
  @IsUUID()
  numeracion_id?: string | null;

  @ApiPropertyOptional({ example: 5, description: 'Descuento máximo sin autorización de supervisor, en %' })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 2 })
  @Min(0, { message: 'El descuento máximo no puede ser negativo' })
  @Max(100, { message: 'El descuento máximo no puede pasar del 100 %' })
  pct_descuento_max?: number;

  @ApiPropertyOptional({ example: 15, description: 'Días de validez de una cotización' })
  @IsOptional()
  @IsInt()
  @Min(1, { message: 'La validez de la cotización es de al menos 1 día' })
  @Max(180, { message: 'La validez de la cotización no puede pasar de 180 días' })
  dias_validez_cotizacion?: number;

  @ApiPropertyOptional({
    example: 3,
    description: 'Interés por mora mensual, en %, para estimar la mora de la cartera',
  })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 4 })
  @Min(0, { message: 'La tasa de mora no puede ser negativa' })
  @Max(20, { message: 'La tasa de mora mensual no puede pasar del 20 %' })
  tasa_mora_mensual?: number;

  @ApiPropertyOptional({
    description: 'Plantilla HTML del boleto con variables {{...}}. Vacía = el modelo por defecto.',
  })
  @IsOptional()
  @IsString()
  @MaxLength(100000)
  plantilla_boleto?: string | null;

  @ApiPropertyOptional({
    example: 10,
    description: 'Rescisión: % de lo cobrado que retiene la empresa (se puede cambiar en cada adenda)',
  })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 2 })
  @Min(0, { message: 'La retención no puede ser negativa' })
  @Max(100, { message: 'La retención no puede pasar del 100 %' })
  pct_retencion_rescision?: number;

  @ApiPropertyOptional({ example: 12, description: 'Meses de garantía desde la entrega' })
  @IsOptional()
  @IsInt()
  @Min(0, { message: 'Los meses de garantía no pueden ser negativos' })
  @Max(120, { message: 'Los meses de garantía no pueden pasar de 120' })
  meses_garantia?: number;

  @ApiPropertyOptional({ example: 5, description: 'Obra: % de fondo de reparo que se retiene en cada certificado' })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 2 })
  @Min(0, { message: 'El fondo de reparo no puede ser negativo' })
  @Max(50, { message: 'El fondo de reparo no puede pasar del 50 %' })
  pct_fondo_reparo?: number;

  @ApiPropertyOptional({
    example: true,
    description: 'Cumplimiento: el boleto exige el legajo de debida diligencia aprobado y vigente de cada comprador',
  })
  @IsOptional()
  @IsBoolean()
  exigir_legajo_cliente?: boolean;

  @ApiPropertyOptional({ example: 24, description: 'Cumplimiento: meses de vigencia de un legajo aprobado' })
  @IsOptional()
  @IsInt()
  @Min(1, { message: 'La vigencia tiene que ser de al menos 1 mes' })
  @Max(60, { message: 'La vigencia no puede pasar de 60 meses' })
  meses_vigencia_legajo?: number;

  @ApiPropertyOptional({ example: 12, description: 'Cumplimiento: meses de vigencia si el riesgo es alto' })
  @IsOptional()
  @IsInt()
  @Min(1, { message: 'La vigencia tiene que ser de al menos 1 mes' })
  @Max(60, { message: 'La vigencia no puede pasar de 60 meses' })
  meses_vigencia_legajo_alto?: number;

  @ApiPropertyOptional({
    example: 75000000,
    description: 'Cumplimiento: cobros en efectivo desde este monto (Gs.) van al registro de operaciones inusuales',
  })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 0 })
  @Min(0)
  umbral_efectivo_gs?: number;

  @ApiPropertyOptional({ example: 30, description: 'Cumplimiento: ventana en días para detectar efectivo fraccionado' })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(365)
  dias_fraccionamiento?: number;
}
