import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
    IsArray,
    IsBoolean,
    IsIn,
    IsNotEmpty,
    IsNumber,
    IsOptional,
    IsString,
    IsUUID,
    Length,
    Matches,
    Max,
    Min,
    ValidateNested,
} from 'class-validator';

export class FacturaCabDto {
  @ApiProperty({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsOptional()
  @IsUUID()
  empresa_id: string;

  @ApiProperty({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsUUID()
  @IsNotEmpty({ message: 'Cliente es obligatorio' })
  cliente_id: string;

  @ApiProperty({ example: '0ba68a57-7e52-487a-8437-6d55f801b935' })
  @IsUUID()
  @IsNotEmpty({ message: 'Tipo transacción es obligatorio' })
  tipo_transaccion_id: string;

  @ApiProperty({ example: '41a49136-e1ac-4bbf-88c8-3d12674ee4e8' })
  @IsUUID()
  @IsNotEmpty({ message: 'Tipo impuesto es obligatorio' })
  tipo_impuesto_id: string;

  @ApiProperty({ example: '9c131c09-bc75-4cf0-b79b-1c28e498564c' })
  @IsUUID()
  @IsNotEmpty({ message: 'Moneda es obligatoria' })
  moneda_id: string;

  @ApiProperty({ example: 'eeec7470-e500-499b-ae44-704b929a1d37' })
  @IsUUID()
  @IsNotEmpty({ message: 'Indicador presencia es obligatorio' })
  indicador_presencia_id: string;

  @ApiProperty({ example: '6b6b4e89-85a4-4b01-9b90-2da0ff11b955' })
  @IsUUID()
  @IsNotEmpty({ message: 'Condición operación es obligatoria' })
  condicion_operacion_id: string;

  @ApiProperty({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsUUID()
  @IsOptional()
  tipo_operacion_id?: string;

  @ApiPropertyOptional({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsUUID()
  @IsOptional()
  sucripcion_id?: string;

  @ApiPropertyOptional({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsUUID()
  @IsOptional()
  @Length(1, 3000, { message: 'Dinfoemi debe tener entre 1 y 3000 caracteres' })
  dinfoemi?: string;

  @ApiPropertyOptional({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsOptional()
  @Length(1, 3000, {
    message: 'Dinfofisc debe tener entre 1 y 3000 caracteres',
  })
  dinfofisc?: string;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'ID de numeración para generar número automáticamente',
  })
  @IsOptional()
  @IsUUID()
  numeracion_id?: string;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'ID del depósito para descuento de inventario (opcional, usa principal si no se especifica)',
  })
  @IsOptional()
  @IsUUID()
  deposito_id?: string;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'ID del vendedor para asignar a la factura',
  })
  @IsOptional()
  @IsUUID()
  vendedor_id?: string;

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

  @ApiPropertyOptional({
    description:
      'Cobro en ruta: emite factura contado pero deja saldo pendiente para que el cobrador la cobre en campo y la rinda. No genera pagos en caja al emitir.',
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  cobro_diferido?: boolean;

  @ApiPropertyOptional({
    example: '001',
    description: 'Establecimiento (opcional si se envía numeracion_id)',
  })
  @IsOptional()
  @Length(1, 3, {
    message: 'Establecimiento debe tener entre 1 y 3 caracteres',
  })
  dest?: string;

  @ApiPropertyOptional({
    example: '001',
    description: 'Punto de expedición (opcional si se envía numeracion_id)',
  })
  @IsOptional()
  @Length(1, 3, {
    message: 'Punto de expedición debe tener entre 1 y 3 caracteres',
  })
  dpunexp?: string;

  @ApiPropertyOptional({
    example: '0000001',
    description: 'Número de documento (opcional si se envía numeracion_id)',
  })
  @IsOptional()
  @Length(1, 7, {
    message: 'Número de documento debe tener entre 1 y 7 caracteres',
  })
  dnumdoc?: string;

  @ApiPropertyOptional({ example: 'AA' })
  @IsOptional()
  @Length(1, 2, { message: 'Serie debe tener entre 1 y 3 caracteres' })
  dserienum?: string;

  @ApiProperty({ example: '2025-11-12 00:00:00' })
  @IsNotEmpty({ message: 'Fecha de emisión es obligatoria' })
  @Length(1, 19, {
    message: 'Fecha de emisión debe tener entre 1 y 19 caracteres',
  })
  dfeemide: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsIn(['1', '2'], { message: 'dCondTiCam debe ser 1 o 2' })
  dcondticam?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNotEmpty({ message: 'dticam es obligatorio' })
  dticam?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsIn(['1', '2'], { message: 'icondant debe ser 1 o 2' })
  icondant: string;

  @ApiPropertyOptional({ example: 'AAAA-MM-DD' })
  @IsOptional()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, {
    message: 'dfecemnr debe tener el formato AAAA-MM-DD',
  })
  @Length(1, 10, { message: 'dfecemnr debe tener entre 1 y 10 caracteres' })
  dfecemnr: string;

  @ApiPropertyOptional({ example: 'email@example.com' })
  @IsOptional()
  @Length(1, 80, { message: 'Email debe tener entre 1 y 80 caracteres' })
  demailadmin?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(2, 2, { message: 'Modalidad debe tener entre 2 y 2 caracteres' })
  dmodcont?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(5, 5, { message: 'Entidad debe tener entre 5 y 5 caracteres' })
  dentcont?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(2, 2, { message: 'Año debe tener entre 2 y 2 caracteres' })
  danocont?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(7, 7, { message: 'Secuencia debe tener entre 7 y 7 caracteres' })
  dseccont?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, {
    message: 'dfecodcont debe tener el formato AAAA-MM-DD',
  })
  @Length(1, 10, {
    message: 'Fecha de emisión del codigo de contratación debe tener entre 1 y 10 caracteres',
  })
  dfecodcont?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(1, 15, { message: 'dciclo debe tener entre 2 y 2 caracteres' })
  dciclo?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, {
    message: 'Fecha inicio del ciclo debe tener el formato AAAA-MM-DD',
  })
  @Length(1, 10, {
    message: 'Fecha inicio del ciclo debe tener entre 1 y 10 caracteres',
  })
  dfecinic?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, {
    message: 'Fecha fin del ciclo debe tener el formato AAAA-MM-DD',
  })
  @Length(1, 10, {
    message: 'Fecha fin del ciclo debe tener entre 1 y 10 caracteres',
  })
  dfecfinc?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, {
    message: 'Fecha vencimiento del pago debe tener el formato AAAA-MM-DD',
  })
  @Length(1, 10, {
    message: 'Fecha vencimiento del pago debe tener entre 1 y 10 caracteres',
  })
  dvencpag?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(1, 30, {
    message: 'Numero de contrato debe tener entre 1 y 30 caracteres',
  })
  dcontrato?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(1, 15, {
    message: 'Saldo anterior debe tener entre 1 y 15 caracteres',
  })
  dsalant?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(1, 5000, {
    message: 'Información adicional debe tener entre 1 y 5000 caracteres',
  })
  dinfadic?: string;

  @ApiPropertyOptional({ example: 'OC-000123' })
  @IsOptional()
  @IsString()
  @Length(1, 15, {
    message: 'Número de orden de compra debe tener entre 1 y 15 caracteres',
  })
  dordcompra?: string;

  @ApiPropertyOptional({ example: 'OV-000456' })
  @IsOptional()
  @IsString()
  @Length(1, 15, {
    message: 'Número de orden de venta debe tener entre 1 y 15 caracteres',
  })
  dordvta?: string;

  @ApiPropertyOptional({ example: '000789' })
  @IsOptional()
  @IsString()
  @Length(1, 10, {
    message: 'Número de asiento contable debe tener entre 1 y 10 caracteres',
  })
  dasiento?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsIn(['1', '2'], {
    message: 'Condición de la operación a crédito debe ser 1 o 2',
  })
  icondcred?: string;

  @ApiPropertyOptional({ description: 'Dirección del receptor editable por factura' })
  @IsOptional()
  @IsString()
  ddirrec?: string;

  @ApiPropertyOptional({ description: 'ID de dirección adicional del cliente usada en esta factura' })
  @IsOptional()
  @IsString()
  cliente_direccion_id?: string;

  @ApiPropertyOptional({ example: '30 dias' })
  @IsOptional()
  @Length(2, 15, {
    message: 'Plazo de crédito debe tener entre 2 y 15 caracteres',
  })
  dplazocre?: string;

  @ApiPropertyOptional({ example: '12' })
  @IsOptional()
  @Min(1, { message: 'Cantidad de cuotas debe ser mínimo 1' })
  @Max(999, { message: 'Cantidad de cuotas debe ser máximo 999' })
  dcuotas?: number;

  @ApiPropertyOptional({
    description: 'ID del plan de cuotas automático aplicado a esta factura (Fase 7). Opcional — null si se usó el selector por producto o carga manual.',
  })
  @IsOptional()
  @IsUUID()
  plan_cuota_id?: string;

  @ApiPropertyOptional()
  @IsOptional()
  dmonent?: number;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'ID del pedido mayorista vinculado a esta factura',
  })
  @IsOptional()
  @IsUUID()
  pedido_id?: string;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'ID de la solicitud de crédito vinculada a esta factura',
  })
  @IsOptional()
  @IsUUID()
  solicitud_credito_id?: string;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description:
      'ID de autorizaciones_caja (tipo=descuento, estado=aprobada) requerida cuando algún ítem supera su tope de descuento. Ver docs/plan-motor-precios-rentabilidad.md §10.',
  })
  @IsOptional()
  @IsUUID()
  autorizacion_descuento_id?: string;
}

// Vínculo ítem de factura → ítem de remisión (flujo Remisión → Factura).
// Un ítem de factura consolidado puede consumir de varios nota_remision_det.
export class AplicacionRemisionDto {
  @ApiProperty({ example: '9ce06294-3e21-450c-96bc-70b3a2523a9e' })
  @IsUUID()
  @IsNotEmpty()
  nota_remision_det_id: string;

  @ApiProperty({ example: 5 })
  @IsNumber()
  @Min(0.0001)
  cantidad: number;
}

export class DetalleFacturaDto {
  @ApiProperty({ example: '9ce06294-3e21-450c-96bc-70b3a2523a9e' })
  @IsUUID()
  @IsNotEmpty({ message: 'Producto es obligatorio' })
  producto_id: string;

  @ApiPropertyOptional({ type: [AplicacionRemisionDto], description: 'Remisiones que cubre este ítem (facturar desde remisión)' })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => AplicacionRemisionDto)
  aplicaciones_remision?: AplicacionRemisionDto[];

  @ApiProperty({ example: 'UNI' })
  @IsNotEmpty({ message: 'Unidad de medida es obligatoria' })
  unidad_medida: string;

  @ApiProperty({ example: 'Producto' })
  @IsNotEmpty({ message: 'Descripción es obligatoria' })
  @Length(1, 2000, {
    message: 'Descripción debe tener entre 1 y 2000 caracteres',
  })
  descripcion: string;

  @ApiProperty({ example: '1' })
  @IsNotEmpty({ message: 'Cantidad es obligatoria' })
  cantidad: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Precio unitario es obligatorio' })
  precio_unitario: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total bruto es obligatorio' })
  total_bruto: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total bruto es obligatorio' })
  descuento: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Porcentaje de descuento es obligatorio' })
  porcentaje_descuento: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Descuento global es obligatorio' })
  descuento_global: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total operación es obligatorio' })
  total_operacion: number;
  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total operación es obligatorio' })
  total_gs: number;

  @ApiProperty({ example: '1' })
  @IsNotEmpty({ message: 'Afectación IVA es obligatoria' })
  @IsIn([1, 2, 3, 4], { message: 'Afectación IVA debe ser 1, 2, 3, 4' })
  afectacion_iva: number;

  @ApiProperty({ example: '10' })
  @IsNotEmpty({ message: 'Porcentaje de IVA es obligatorio' })
  @IsIn([10, 5, 0], { message: 'Porcentaje de IVA debe ser 10, 5 o 0' })
  porcentaje_iva: number;

  @ApiProperty({ example: '100' })
  @IsNotEmpty({ message: 'Proporción de IVA es obligatorio' })
  @Min(0, { message: 'Proporción de IVA debe ser un número entre 0 y 100' })
  @Max(100, { message: 'Proporción de IVA debe ser un número entre 0 y 100' })
  proporcion_iva: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Base gravada es obligatorio' })
  base_gravada: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Liquidación IVA es obligatorio' })
  liquidacion_iva: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Base gravada exenta es obligatorio' })
  base_gravada_exenta: number;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(1, 5000, {
    message: 'Información adicional debe tener entre 1 y 5000 caracteres',
  })
  info_adicional_item?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @Length(3, 3, { message: 'Pais de origen debe tener entre 3 y 3 caracteres' })
  pais_origen?: string;
  @ApiPropertyOptional()
  @IsOptional()
  tipo_cambio_item?: number;

  @ApiPropertyOptional()
  @IsOptional()
  cdc_anticipo_item?: string;

  @ApiPropertyOptional()
  @IsOptional()
  anticipo_precio_unitario?: number;
}

export class FormaPagoDto {
  @ApiPropertyOptional({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsOptional()
  @IsUUID()
  sesion_caja_id?: string;

  @ApiProperty({ example: '9044b1a1-ba0e-4803-8ff8-c3870466b46c' })
  @IsUUID()
  @IsNotEmpty({ message: 'Medio de pago es obligatorio' })
  medio_pago_id: string;

  @ApiPropertyOptional({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsOptional()
  @IsUUID()
  @IsNotEmpty({ message: 'Tarjeta es obligatoria' })
  tarjeta_id?: string;

  @ApiPropertyOptional({ example: 'Otra tarjeta' })
  @IsOptional()
  @Length(4, 20, {
    message: 'La descripcion de la tarjeta debe tener entre 4 y 20 caracteres',
  })
  tarjeta_descripcion_otro?: string;

  @ApiProperty({ example: '1cfdf379-8225-4c7e-b572-c5fa6983c846' })
  @IsUUID()
  @IsNotEmpty({ message: 'Forma de procesamiento de pago es obligatoria' })
  forma_procesamiento_pago_id?: string;

  @ApiProperty({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsUUID()
  @IsNotEmpty({ message: 'Moneda es obligatoria' })
  moneda_id: string;

  @ApiPropertyOptional({ example: '0' })
  @IsOptional()
  monto_pago?: number;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'ID de la moneda en que se realiza el pago (si difiere de la moneda de la factura)',
  })
  @IsOptional()
  @IsUUID()
  moneda_pago_id?: string;

  @ApiPropertyOptional({ example: 100, description: 'Monto en la moneda original del pago (antes de conversión)' })
  @IsOptional()
  monto_moneda_original?: number;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(4, 60, {
    message: 'Razón social de la procesadora de tarjeta debe tener entre 4 y 60 caracteres',
  })
  razon_social_procesadora?: string;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(3, 8, {
    message: 'Ruc de la procesadora de tarjeta debe tener entre 3 y 8 caracteres',
  })
  ruc_procesadora?: string;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(1, 1, {
    message: 'Dígito verificador de la procesadora de tarjeta debe tener entre 1 y 1 caracteres',
  })
  dv_procesadora?: string;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(6, 10, {
    message: 'Nro de autorización de la procesadora de tarjeta debe tener entre 6 y 10 caracteres',
  })
  nro_autorizacion_procesadora?: string;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(4, 30, {
    message: 'Nombre titular de la tarjeta debe tener entre 4 y 30 caracteres',
  })
  nombre_titular_tarjeta?: string;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(4, 4, {
    message: 'La tarjeta debe tener 4 digitos (Ultimos 4 digitos)',
  })
  numero_tarjeta?: string;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(8, 8, { message: 'El cheque debe tener 8 digitos' })
  numero_cheque?: string;

  @ApiPropertyOptional({ example: '' })
  @IsOptional()
  @Length(4, 20, {
    message: 'Banco emisor del cheque debe tener entre 4 y 20 caracteres',
  })
  banco_emisor?: string;
}

export class SubtotalDto {
  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Subtotal exento es obligatorio' })
  @IsNumber({}, { message: 'Subtotal exento debe ser numérico' })
  subtotal_exento: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Subtotal exonerado es obligatorio' })
  @IsNumber({}, { message: 'Subtotal exonerado debe ser numérico' })
  subtotal_exonerado: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Subtotal IVA 5% es obligatorio' })
  @IsNumber({}, { message: 'Subtotal IVA 5% debe ser numérico' })
  subtotal_5: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Subtotal IVA 10% es obligatorio' })
  @IsNumber({}, { message: 'Total IVA 10% debe ser numérico' })
  subtotal_10: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Liquidación IVA 5% es obligatorio' })
  @IsNumber({}, { message: 'Liquidación IVA 5% debe ser numérico' })
  liquidacion_iva_5: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Liquidación IVA 10% es obligatorio' })
  @IsNumber({}, { message: 'Liquidación IVA 10% debe ser numérico' })
  liquidacion_iva_10: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Liquidación redondeo es obligatorio' })
  @IsNumber({}, { message: 'Liquidación redondeo debe ser numérico' })
  liquidacion_redondeo_5: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Liquidación redondeo es obligatorio' })
  @IsNumber({}, { message: 'Liquidación redondeo debe ser numérico' })
  liquidacion_redondeo_10: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Liquidación IVA comisión es obligatorio' })
  @IsNumber({}, { message: 'Liquidación IVA comisión debe ser numérico' })
  liquidacion_iva_comision: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total IVA es obligatorio' })
  @IsNumber({}, { message: 'Total IVA debe ser numérico' })
  total_iva: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total operación es obligatorio' })
  @IsNumber({}, { message: 'Total operación debe ser numérico' })
  total_operacion: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total descuento es obligatorio' })
  @IsNumber({}, { message: 'Total descuento debe ser numérico' })
  total_descuento: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total descuento global es obligatorio' })
  @IsNumber({}, { message: 'Total descuento global debe ser numérico' })
  total_descuento_global_item: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total descuento particular item es obligatorio' })
  @IsNumber({}, { message: 'Total descuento particular item debe ser numérico' })
  total_descuento_particular_item: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total bruto operación es obligatorio' })
  @IsNumber({}, { message: 'Total bruto operación debe ser numérico' })
  total_bruto_operacion: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total anticipo item es obligatorio' })
  @IsNumber({}, { message: 'Total anticipo item debe ser numérico' })
  total_anticipo_item: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total anticipo global es obligatorio' })
  @IsNumber({}, { message: 'Total anticipo global debe ser numérico' })
  total_anticipo_global_item: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Porcentaje de descuento total es obligatorio' })
  @IsNumber({}, { message: 'Porcentaje de descuento total debe ser numérico' })
  porcentaje_descuento_total: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total anticipo es obligatorio' })
  @IsNumber({}, { message: 'Total anticipo debe ser numérico' })
  total_anticipo_operacion: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total redondeo es obligatorio' })
  @IsNumber({}, { message: 'Total redondeo debe ser numérico' })
  total_redondeo: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total comisión es obligatorio' })
  @IsNumber({}, { message: 'Total comisión debe ser numérico' })
  total_comision: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total general operación es obligatorio' })
  @IsNumber({}, { message: 'Total general operación debe ser numérico' })
  total_general_operacion: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total general operación es obligatorio' })
  @IsNumber({}, { message: 'Total general operación debe ser numérico' })
  total_base_gravada_5: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total general operación es obligatorio' })
  @IsNumber({}, { message: 'Total general operación debe ser numérico' })
  total_base_gravada_10: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total base gravada es obligatorio' })
  @IsNumber({}, { message: 'Total base gravada debe ser numérico' })
  total_base_gravada: number;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Total gs es obligatorio' })
  @IsNumber({}, { message: 'Total gs debe ser numérico' })
  total_gs: number;
}

export class CuotasDto {
  @ApiPropertyOptional({ example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf' })
  @IsUUID()
  @IsOptional()
  @IsNotEmpty({ message: 'Cuenta es obligatoria' })
  cuenta_id?: string;

  @ApiProperty({ example: 'PYG' })
  @IsNotEmpty({ message: 'Moneda es obligatoria' })
  @IsString({ message: 'Moneda debe ser una cadena' })
  @Length(3, 3, { message: 'Moneda debe tener entre 3 y 3 caracteres' })
  moneda_iso: string;

  @ApiProperty({ example: '0' })
  @IsNotEmpty({ message: 'Monto de cuota es obligatorio' })
  @IsNumber({}, { message: 'Monto de cuota debe ser numérico' })
  monto_cuota: number;

  @ApiProperty({ example: '1' })
  @IsNotEmpty({ message: 'Cantidad de cuotas es obligatoria' })
  @IsNumber({}, { message: 'Cantidad de cuotas debe ser numérico' })
  nro_cuota: number;

  @ApiProperty({ example: '2025-12-12' })
  @IsNotEmpty({ message: 'Fecha de vencimiento es obligatoria' })
  @Matches(/^\d{4}-\d{2}-\d{2}$/, {
    message: 'Fecha de vencimiento debe ser una fecha con el formato AAAA-MM-DD',
  })
  vencimiento: string;

  @ApiPropertyOptional({ example: '0' })
  @IsOptional()
  @IsNumber({}, { message: 'Saldo pendiente debe ser numérico' })
  saldo_pendiente?: number;
}

export class CreateFacturaDto {
  @ApiProperty({ type: FacturaCabDto })
  @ValidateNested()
  @Type(() => FacturaCabDto)
  cabecera: FacturaCabDto;

  @ApiProperty({ type: [DetalleFacturaDto] })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => DetalleFacturaDto)
  items: DetalleFacturaDto[];

  @ApiPropertyOptional({ type: [FormaPagoDto] })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => FormaPagoDto)
  pagos?: FormaPagoDto[];

  @ApiProperty({ type: SubtotalDto })
  @ValidateNested()
  @Type(() => SubtotalDto)
  subtotal: SubtotalDto;

  @ApiPropertyOptional({ type: [CuotasDto] })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => CuotasDto)
  cuotas?: CuotasDto[];
}

export class CreateFacturaAutomaticoDto {
  @ApiProperty({ type: FacturaCabDto })
  @ValidateNested()
  @Type(() => FacturaCabDto)
  cabecera: FacturaCabDto;

  @ApiProperty({ type: [DetalleFacturaDto] })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => DetalleFacturaDto)
  items: DetalleFacturaDto[];

  @ApiPropertyOptional({ type: [FormaPagoDto] })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => FormaPagoDto)
  pagos?: FormaPagoDto[];

  @ApiProperty({ type: SubtotalDto })
  @ValidateNested()
  @Type(() => SubtotalDto)
  subtotal: SubtotalDto;

  @ApiPropertyOptional({ type: [CuotasDto] })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => CuotasDto)
  cuotas?: CuotasDto[];
}
