import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  IsArray,
  IsDateString,
  IsInt,
  IsNotEmpty,
  IsNumber,
  IsObject,
  IsOptional,
  IsString,
  IsUUID,
  Min,
  ValidateNested,
} from 'class-validator';

export class CronogramaCuotaDto {
  @ApiProperty({ description: 'Número de cuota' })
  @IsInt()
  @Min(1)
  nro_cuota: number;

  @ApiProperty({ description: 'Monto de la cuota' })
  @IsNumber()
  @Min(0)
  monto_cuota: number;

  @ApiProperty({ description: 'Fecha de vencimiento (YYYY-MM-DD)' })
  @IsString()
  fecha_vencimiento: string;

  @ApiPropertyOptional({ description: 'Saldo pendiente al momento de esta cuota' })
  @IsOptional()
  @IsNumber()
  saldo_pendiente?: number;
}

export class CreateSolicitudCreditoItemDto {
  @ApiProperty({ description: 'ID del producto' })
  @IsNotEmpty()
  @IsUUID()
  producto_id: string;

  @ApiPropertyOptional({ description: 'ID del plan de cuotas seleccionado' })
  @IsOptional()
  @IsUUID()
  producto_precio_cuota_id?: string;

  @ApiProperty({ description: 'Cantidad' })
  @IsNotEmpty()
  @IsNumber()
  @Min(0.0001)
  cantidad: number;

  @ApiPropertyOptional({ description: 'Descripción del producto' })
  @IsOptional()
  @IsString()
  descripcion?: string;

  @ApiPropertyOptional({ description: 'Cantidad de cuotas' })
  @IsOptional()
  @IsInt()
  @Min(1)
  cant_cuotas?: number;

  @ApiPropertyOptional({ description: 'Monto por cuota' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  monto_cuota?: number;

  @ApiPropertyOptional({ description: 'Cuota inicial / entrada' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  cuota_inicial?: number;

  @ApiPropertyOptional({ description: 'Precio total del item' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  precio_total?: number;

  @ApiPropertyOptional({ description: 'Precio unitario (precio_total / cantidad)' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  precio_unitario?: number;

  @ApiPropertyOptional({ description: 'Porcentaje de IVA' })
  @IsOptional()
  @IsInt()
  porcentaje_iva?: number;

  @ApiPropertyOptional({ description: 'Observación del item' })
  @IsOptional()
  @IsString()
  observacion?: string;
}

export class CreateSolicitudCreditoDto {
  @ApiProperty({ description: 'ID del cliente' })
  @IsNotEmpty()
  @IsUUID()
  cliente_id: string;

  @ApiPropertyOptional({ description: 'ID de la sucursal' })
  @IsOptional()
  @IsUUID()
  sucursal_id?: string;

  @ApiPropertyOptional({ description: 'ID del vendedor' })
  @IsOptional()
  @IsUUID()
  vendedor_id?: string;

  @ApiPropertyOptional({ description: 'ID del cobrador asignado a esta solicitud' })
  @IsOptional()
  @IsUUID()
  cobrador_id?: string;

  @ApiPropertyOptional({ description: 'Día fijo de la semana para cobro semanal (1=Lunes, 7=Domingo). Null = sin restricción por día de semana' })
  @IsOptional()
  @IsInt()
  @Min(1)
  dia_cobro_semana?: number;

  @ApiPropertyOptional({ description: 'ID de la condición de pago' })
  @IsOptional()
  @IsUUID()
  condicion_pago_id?: string;

  @ApiPropertyOptional({ description: 'ID del plan de cuotas automático aplicado (Fase 7)' })
  @IsOptional()
  @IsUUID()
  plan_cuota_id?: string;

  @ApiPropertyOptional({ description: 'ID del punto de expedición' })
  @IsOptional()
  @IsUUID()
  punto_expedicion_id?: string;

  @ApiPropertyOptional({ description: 'ID de la numeración' })
  @IsOptional()
  @IsUUID()
  numeracion_id?: string;

  @ApiPropertyOptional({ description: 'Moneda (default PYG)', default: 'PYG' })
  @IsOptional()
  @IsString()
  moneda?: string;

  // ═══ Condiciones del crédito ═══

  @ApiPropertyOptional({ description: 'Intervalo entre cuotas en días (7=semanal, 15=quincenal, 30=mensual)', default: 30 })
  @IsOptional()
  @IsInt()
  @Min(1)
  intervalo_dias?: number;

  @ApiPropertyOptional({ description: 'Monto de entrega inicial (pago al contado antes de las cuotas)' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  cuota_inicial_total?: number;

  @ApiPropertyOptional({ description: 'Fecha de vencimiento de la primera cuota (YYYY-MM-DD)' })
  @IsOptional()
  @IsString()
  fecha_primera_cuota?: string;

  @ApiPropertyOptional({ description: 'Día fijo del mes (1-31, mensual o primera quincena). null = por intervalo' })
  @IsOptional()
  @IsInt()
  @Min(1)
  dia_fijo_pago_1?: number;

  @ApiPropertyOptional({ description: 'Segundo día del mes (1-31, solo quincenal). null = una sola quincena' })
  @IsOptional()
  @IsInt()
  @Min(1)
  dia_fijo_pago_2?: number;

  @ApiPropertyOptional({ description: 'Override del período de gracia (días). null = hereda cob_config_mora' })
  @IsOptional()
  @IsInt()
  @Min(0)
  dias_gracia_override?: number;

  @ApiPropertyOptional({ description: 'Cantidad total de cuotas' })
  @IsOptional()
  @IsInt()
  @Min(1)
  cant_cuotas?: number;

  // ═══ Totales ═══

  @ApiPropertyOptional({ description: 'Monto total de la solicitud (suma de items)' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  monto_total?: number;

  @ApiPropertyOptional({ description: 'Saldo a financiar (monto_total - cuota_inicial_total)' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  saldo_financiar?: number;

  @ApiPropertyOptional({ description: 'Observaciones' })
  @IsOptional()
  @IsString()
  observaciones?: string;

  @ApiPropertyOptional({ description: 'Estado inicial (borrador o pendiente_aprobacion). Default: pendiente_aprobacion', default: 'pendiente_aprobacion' })
  @IsOptional()
  @IsString()
  estado?: string;

  // ═══ Items ═══

  @ApiPropertyOptional({ description: 'Items de la solicitud', type: [CreateSolicitudCreditoItemDto] })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => CreateSolicitudCreditoItemDto)
  items?: CreateSolicitudCreditoItemDto[];

  // ═══ Cronograma precalculado (fuente de verdad para cuentas a cobrar) ═══

  @ApiPropertyOptional({ description: 'Cronograma de cuotas con fechas y montos', type: [CronogramaCuotaDto] })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => CronogramaCuotaDto)
  cronograma?: CronogramaCuotaDto[];
}
