import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { AnnouncementCategory, AnnouncementPriority, NotificationChannel, UserRole } from '@prisma/client';
import {
  ArrayUnique,
  IsArray,
  IsDate,
  IsEnum,
  IsObject,
  IsOptional,
  IsString,
  MaxLength,
  MinLength
} from 'class-validator';
import { Type } from 'class-transformer';
import { ESTATE_ID_EXAMPLE } from '../../common/swagger-docs';

export class CreateAnnouncementDto {
  @ApiProperty({ example: ESTATE_ID_EXAMPLE, description: 'Estate that receives the announcement.' })
  @IsString()
  estateId!: string;

  @ApiProperty({ example: 'Main gate maintenance', description: 'Announcement title, capped at 80 characters.' })
  @IsString()
  @MinLength(3)
  @MaxLength(80)
  title!: string;

  @ApiProperty({ example: 'The main gate scanner will be serviced on Saturday morning.', description: 'Announcement body.' })
  @IsString()
  @MinLength(5)
  @MaxLength(700)
  body!: string;

  @ApiProperty({ enum: AnnouncementCategory, example: AnnouncementCategory.MAINTENANCE })
  @IsEnum(AnnouncementCategory)
  category!: AnnouncementCategory;

  @ApiPropertyOptional({ enum: AnnouncementPriority, example: AnnouncementPriority.NORMAL })
  @IsOptional()
  @IsEnum(AnnouncementPriority)
  priority?: AnnouncementPriority;

  @ApiPropertyOptional({ enum: UserRole, isArray: true, example: [UserRole.RESIDENT], description: 'Optional target roles. Defaults to residents.' })
  @IsOptional()
  @IsArray()
  @ArrayUnique()
  @IsEnum(UserRole, { each: true })
  targetRoles?: UserRole[];

  @ApiPropertyOptional({ example: ['user-uuid'], description: 'Optional exact target user IDs.' })
  @IsOptional()
  @IsArray()
  @ArrayUnique()
  @IsString({ each: true })
  targetUserIds?: string[];

  @ApiPropertyOptional({ enum: NotificationChannel, isArray: true, example: [NotificationChannel.IN_APP, NotificationChannel.PUSH] })
  @IsOptional()
  @IsArray()
  @ArrayUnique()
  @IsEnum(NotificationChannel, { each: true })
  deliveryChannels?: NotificationChannel[];

  @ApiPropertyOptional({ example: '2026-05-31T18:00:00.000Z', description: 'Optional expiry date.' })
  @IsOptional()
  @Type(() => Date)
  @IsDate()
  expiresAt?: Date;

  @ApiPropertyOptional({ example: { requiresApproval: false }, description: 'Optional metadata.' })
  @IsOptional()
  @IsObject()
  metadata?: Record<string, unknown>;
}
