import { ApiPropertyOptional } from '@nestjs/swagger'; import { IsArray, ArrayMaxSize, IsBoolean, IsInt, IsLatitude, IsLongitude, IsOptional, IsString, IsUUID, Matches, Max, MaxLength, Min, } from 'class-validator'; export class UpdateBusinessDto { @ApiPropertyOptional({ example: 'Shine Carwash' }) @IsOptional() @IsString() @MaxLength(150) title?: string; @ApiPropertyOptional({ example: 'shine-carwash' }) @IsOptional() @IsString() @MaxLength(120) @Matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, { message: 'slug must be lowercase words separated by hyphens', }) slug?: string; @ApiPropertyOptional({ format: 'uuid' }) @IsOptional() @IsUUID() categoryId?: string; @ApiPropertyOptional({ example: 'تمیزی که می‌درخشد', nullable: true }) @IsOptional() @IsString() @MaxLength(150) subtitle?: string | null; @ApiPropertyOptional({ example: 'Premium carwash service', nullable: true }) @IsOptional() @IsString() @MaxLength(500) description?: string | null; @ApiPropertyOptional({ example: '09123456789', nullable: true }) @IsOptional() @IsString() @MaxLength(20) contactPhone?: string | null; @ApiPropertyOptional({ example: 'Main street', nullable: true }) @IsOptional() @IsString() @MaxLength(500) address?: string | null; @ApiPropertyOptional({ example: 35.6892, nullable: true }) @IsOptional() @IsLatitude() latitude?: number | null; @ApiPropertyOptional({ example: 51.389, nullable: true }) @IsOptional() @IsLongitude() longitude?: number | null; @ApiPropertyOptional({ format: 'uuid', nullable: true }) @IsOptional() @IsUUID() ownerId?: string | null; @ApiPropertyOptional({ example: true }) @IsOptional() @IsBoolean() isActive?: boolean; @ApiPropertyOptional({ example: false, description: 'When true, services are priced per owner-defined class (e.g. car size)', }) @IsOptional() @IsBoolean() serviceClassesEnabled?: boolean; @ApiPropertyOptional({ example: 1, description: 'How many customers can be served at the same time', minimum: 1, maximum: 20, }) @IsOptional() @IsInt() @Min(1) @Max(20) concurrentCapacity?: number; @ApiPropertyOptional({ example: 30, description: 'Minutes between available booking slot start times', minimum: 5, maximum: 120, }) @IsOptional() @IsInt() @Min(5) @Max(120) slotStepMinutes?: number; @ApiPropertyOptional({ example: false, description: 'When true, customer bookings are approved automatically and proceed to online payment', }) @IsOptional() @IsBoolean() autoApproveBookings?: boolean; @ApiPropertyOptional({ example: false, description: 'When true, customers see an optional gratuity (tip) step after rating a completed booking', }) @IsOptional() @IsBoolean() tipsEnabled?: boolean; @ApiPropertyOptional({ example: true, description: 'When true, a promotional percentage discount is active for this business', }) @IsOptional() @IsBoolean() promoDiscountEnabled?: boolean; @ApiPropertyOptional({ example: 'اولین رزرو شما', nullable: true, description: 'Display title for the promo (owner-defined)', }) @IsOptional() @IsString() @MaxLength(150) promoDiscountTitle?: string | null; @ApiPropertyOptional({ example: 10, nullable: true, description: 'Discount percent (1–100)', minimum: 1, maximum: 100, }) @IsOptional() @IsInt() @Min(1) @Max(100) promoDiscountPercent?: number | null; @ApiPropertyOptional({ example: 'NEW10', nullable: true, description: 'Display code shown to customers (auto-applied when eligible)', }) @IsOptional() @IsString() @MaxLength(40) promoDiscountCode?: string | null; @ApiPropertyOptional({ example: 'first_booking', enum: ['first_booking', 'always'], description: 'first_booking = only the customer’s first booking at this business; always = every booking while enabled', }) @IsOptional() @IsString() @Matches(/^(first_booking|always)$/) promoDiscountMode?: 'first_booking' | 'always'; @ApiPropertyOptional({ type: [String], example: ['customer_satisfaction', 'professional_staff', 'online_booking'], description: 'Up to 3 highlight keys from the platform catalog for the landing hero', }) @IsOptional() @IsArray() @ArrayMaxSize(3) @IsString({ each: true }) heroHighlightKeys?: string[] | null; }