import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  ArrayMaxSize,
  ArrayNotEmpty,
  IsArray,
  IsBoolean,
  IsInt,
  IsNotEmptyObject,
  IsOptional,
  IsUUID,
  ValidateNested,
} from 'class-validator';

/**
 * Tope de productos que se pueden modificar en una sola llamada a `PATCH /productos/bulk`.
 * El frontend parte la selección en lotes de este tamaño cuando el usuario selecciona
 * "todos los resultados del filtro" (catálogos de miles de productos).
 */
export const BULK_PRODUCTOS_MAX_IDS = 1000;

/**
 * Tope de IDs que devuelve `GET /productos/bulk/ids` (selección "todos los resultados
 * del filtro"). Solo devuelve IDs, así que es una consulta barata, pero igual se acota.
 */
export const BULK_PRODUCTOS_MAX_IDS_SELECCION = 20000;

/**
 * Campos simples habilitados para edición masiva.
 * Solo se aceptan campos escalares que no requieran recalcular nada del producto
 * (nada de precios/stock/variantes: esos tienen flujos propios).
 */
export class BulkProductoCambiosDto {
  @ApiPropertyOptional({
    example: true,
    description: 'Publicar (true) o despublicar (false) los productos en el canal ecommerce',
  })
  @IsOptional()
  @IsBoolean({ message: 'mostrar_en_ecommerce debe ser booleano' })
  mostrar_en_ecommerce?: boolean;

  @ApiPropertyOptional({ example: true, description: 'Activar (true) o desactivar (false) los productos' })
  @IsOptional()
  @IsBoolean({ message: 'active debe ser booleano' })
  active?: boolean;

  @ApiPropertyOptional({ example: false, description: 'Marcar o desmarcar los productos como destacados (POS)' })
  @IsOptional()
  @IsBoolean({ message: 'destacado debe ser booleano' })
  destacado?: boolean;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'Reasignar categoría. Enviar null para quitarla.',
    nullable: true,
  })
  @IsOptional()
  @IsUUID(undefined, { message: 'categoria_id debe ser un UUID válido' })
  categoria_id?: string | null;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description: 'Reasignar marca. Enviar null para quitarla.',
    nullable: true,
  })
  @IsOptional()
  @IsUUID(undefined, { message: 'marca_id debe ser un UUID válido' })
  marca_id?: string | null;

  @ApiPropertyOptional({
    example: 'cd88ac6a-2b0e-41bc-afd9-24b594cb8daf',
    description:
      'Afectación de IVA. Obligatorio si se envía porcentaje_iva o proporcion_iva: los tres se validan como un grupo.',
  })
  @IsOptional()
  @IsUUID(undefined, { message: 'afectacion_id debe ser un UUID válido' })
  afectacion_id?: string;

  @ApiPropertyOptional({ example: 10, description: 'Porcentaje de IVA. Debe ir junto con afectacion_id.' })
  @IsOptional()
  @IsInt({ message: 'porcentaje_iva debe ser un número entero' })
  porcentaje_iva?: number;

  @ApiPropertyOptional({ example: 100, description: 'Proporción de IVA. Debe ir junto con afectacion_id.' })
  @IsOptional()
  @IsInt({ message: 'proporcion_iva debe ser un número entero' })
  proporcion_iva?: number;

  @ApiPropertyOptional({ example: true, description: 'Activar o desactivar el manejo de lotes' })
  @IsOptional()
  @IsBoolean({ message: 'maneja_lote debe ser booleano' })
  maneja_lote?: boolean;
}

export class BulkUpdateProductosDto {
  @ApiProperty({
    type: [String],
    example: ['cd88ac6a-2b0e-41bc-afd9-24b594cb8daf', '9f1b2c3d-4e5f-6789-abcd-ef0123456789'],
    description: `IDs de los productos a modificar (máximo ${BULK_PRODUCTOS_MAX_IDS} por solicitud)`,
  })
  @IsArray({ message: 'ids debe ser un arreglo' })
  @ArrayNotEmpty({ message: 'Debe seleccionar al menos un producto' })
  @ArrayMaxSize(BULK_PRODUCTOS_MAX_IDS, {
    message: `No se pueden actualizar más de ${BULK_PRODUCTOS_MAX_IDS} productos por solicitud`,
  })
  @IsUUID(undefined, { each: true, message: 'Los IDs de producto deben ser UUID válidos' })
  ids: string[];

  @ApiProperty({ type: BulkProductoCambiosDto, description: 'Campos a modificar en todos los productos seleccionados' })
  @IsNotEmptyObject({ nullable: false }, { message: 'Debe indicar al menos un campo a modificar' })
  @ValidateNested()
  @Type(() => BulkProductoCambiosDto)
  cambios: BulkProductoCambiosDto;
}
