import { IsString, IsEnum, IsOptional, IsArray, IsBoolean, Matches } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

/** A single channel, or a comma-separated list of them (e.g. "SMS,EMAIL"). */
const CHANNEL_LIST_RE = /^(EMAIL|SMS|PUSH|IN_APP)(,(EMAIL|SMS|PUSH|IN_APP))*$/;
const CHANNEL_MSG = 'channel must be a comma-separated list of EMAIL, SMS, PUSH, IN_APP';

export enum NotificationCategoryEnum {
  BOOKING = 'BOOKING',
  PAYMENT = 'PAYMENT',
  DISRUPTION = 'DISRUPTION',
  PROMOTION = 'PROMOTION',
  SYSTEM = 'SYSTEM',
}

export class SendNotificationDto {
  @ApiProperty() @IsString() passengerId: string;
  @ApiProperty({ example: 'Platform Change' }) @IsString() title: string;
  @ApiProperty({ example: 'Your train departs from Platform 3' }) @IsString() body: string;
  @ApiProperty({ enum: NotificationCategoryEnum }) @IsEnum(NotificationCategoryEnum) category: NotificationCategoryEnum;
  @ApiPropertyOptional({ example: 'edr://tickets/tkt_01' }) @IsOptional() @IsString() deepLink?: string;
  @ApiPropertyOptional() @IsOptional() metadata?: Record<string, any>;
}

export class CreateTemplateDto {
  @ApiProperty({ example: 'booking.created', description: 'Unique template code / event key' })
  @IsString()
  code: string;

  @ApiProperty({ example: 'SMS,EMAIL', description: 'Comma-separated channels: EMAIL, SMS, PUSH, IN_APP' })
  @IsString()
  @Matches(CHANNEL_LIST_RE, { message: CHANNEL_MSG })
  channel: string;

  @ApiPropertyOptional({ example: 'Your train ticket is booked' })
  @IsOptional()
  @IsString()
  subject?: string;

  @ApiProperty({ example: 'Dear {{passengerName}}, your booking {{bookingRef}} is booked.' })
  @IsString()
  bodyTemplate: string;

  @ApiPropertyOptional({ example: true, description: 'Defaults to true' })
  @IsOptional()
  @IsBoolean()
  active?: boolean;
}

// `code` is intentionally omitted — it is the immutable event key and cannot be changed.
export class UpdateTemplateDto {
  @ApiPropertyOptional({ example: 'SMS,EMAIL' })
  @IsOptional()
  @IsString()
  @Matches(CHANNEL_LIST_RE, { message: CHANNEL_MSG })
  channel?: string;

  @ApiPropertyOptional({ example: 'Your train ticket is booked' })
  @IsOptional()
  @IsString()
  subject?: string;

  @ApiPropertyOptional({ example: 'Dear {{passengerName}}, ...' })
  @IsOptional()
  @IsString()
  bodyTemplate?: string;

  @ApiPropertyOptional({ example: true })
  @IsOptional()
  @IsBoolean()
  active?: boolean;
}

export class TestNotificationDto {
  @ApiProperty({ example: 'booking.created' })
  @IsString()
  templateKey: string;

  @ApiProperty({ example: 'user@example.com' })
  @IsString()
  recipient: string;

  @ApiProperty({ example: { bookingRef: 'EDR123456', passengerName: 'John Doe' } })
  context: Record<string, unknown>;

  @ApiPropertyOptional({ example: ['EMAIL', 'SMS', 'IN_APP'] })
  @IsOptional()
  @IsArray()
  channels?: string[];
}
