import {
  IsArray,
  IsDecimal,
  IsEnum,
  IsNotEmpty,
  IsNumber,
  IsOptional,
  IsPositive,
  IsString,
  IsUUID,
  Min,
  ValidateNested,
} from 'class-validator';
import { Transform, Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { PaymentMethod } from '@prisma/client';

export class CreateSaleItemDto {
  @ApiProperty({
    description: 'Product ID',
    example: 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
  })
  @IsUUID(4, { message: 'Product ID must be a valid UUID' })
  @IsNotEmpty({ message: 'Product ID is required' })
  productId: string;

  @ApiProperty({
    description: 'Quantity of the product',
    minimum: 1,
    example: 2,
  })
  @IsNumber({}, { message: 'Quantity must be a number' })
  @IsPositive({ message: 'Quantity must be positive' })
  @Min(1, { message: 'Quantity must be at least 1' })
  @Transform(({ value }) => parseInt(value))
  quantity: number;

  @ApiPropertyOptional({
    description: 'Unit price override (if different from product price)',
    example: 29.99,
  })
  @IsOptional()
  @IsNumber({}, { message: 'Unit price must be a number' })
  @IsPositive({ message: 'Unit price must be positive' })
  @Transform(({ value }) => (value ? parseFloat(value) : undefined))
  unitPrice?: number;
}

export class CreateSaleDto {
  @ApiProperty({
    description: 'Array of sale items',
    type: [CreateSaleItemDto],
  })
  @IsArray({ message: 'Items must be an array' })
  @ValidateNested({ each: true })
  @Type(() => CreateSaleItemDto)
  @IsNotEmpty({ message: 'Items array cannot be empty' })
  items: CreateSaleItemDto[];

  @ApiProperty({
    description: 'Payment method',
    enum: PaymentMethod,
    example: 'CASH',
  })
  @IsEnum(PaymentMethod, { message: 'Invalid payment method' })
  @IsNotEmpty({ message: 'Payment method is required' })
  paymentMethod: PaymentMethod;

  @ApiPropertyOptional({
    description: 'Customer name',
    example: 'John Doe',
  })
  @IsOptional()
  @IsString({ message: 'Customer name must be a string' })
  @Transform(({ value }) => value?.trim())
  customerName?: string;

  @ApiPropertyOptional({
    description: 'Customer email',
    example: 'john@example.com',
  })
  @IsOptional()
  @IsString({ message: 'Customer email must be a string' })
  @Transform(({ value }) => value?.trim().toLowerCase())
  customerEmail?: string;

  @ApiPropertyOptional({
    description: 'Customer phone',
    example: '+1234567890',
  })
  @IsOptional()
  @IsString({ message: 'Customer phone must be a string' })
  @Transform(({ value }) => value?.trim())
  customerPhone?: string;

  @ApiPropertyOptional({
    description: 'Tax amount',
    example: 2.50,
    minimum: 0,
  })
  @IsOptional()
  @IsNumber({}, { message: 'Tax amount must be a number' })
  @Min(0, { message: 'Tax amount cannot be negative' })
  @Transform(({ value }) => (value ? parseFloat(value) : 0))
  taxAmount?: number;

  @ApiPropertyOptional({
    description: 'Discount amount',
    example: 5.00,
    minimum: 0,
  })
  @IsOptional()
  @IsNumber({}, { message: 'Discount amount must be a number' })
  @Min(0, { message: 'Discount amount cannot be negative' })
  @Transform(({ value }) => (value ? parseFloat(value) : 0))
  discountAmount?: number;

  @ApiPropertyOptional({
    description: 'Additional notes for the sale',
    example: 'Customer requested gift wrap',
  })
  @IsOptional()
  @IsString({ message: 'Notes must be a string' })
  @Transform(({ value }) => value?.trim())
  notes?: string;
}