import {
  IsString,
  IsEnum,
  IsObject,
  ValidateNested,
  IsUUID,
  IsOptional,
  ValidateIf,
  MinLength,
  Matches,
  ValidationArguments,
  registerDecorator,
  ValidationOptions,
} from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';
import { RequestType } from '../enums/request-type.enum';

// Custom validator to ensure at least one of workflowCode or workflowId is provided
function IsWorkflowProvided(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: 'isWorkflowProvided',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          const obj = args.object as any;
          return !!(obj.workflowCode || obj.workflowId);
        },
        defaultMessage(args: ValidationArguments) {
          return 'Either workflowCode or workflowId must be provided';
        },
      },
    });
  };
}

export class RequestMetadataDto {
  [key: string]: any;
}

export class CreateRequestDto {
  @ApiProperty({
    description: 'Workflow code or ID for the request',
    example: 'FIRE_SAFETY_CERT',
  })
  @IsOptional()
  @IsString({ message: 'workflowCode must be a string' })
  @IsWorkflowProvided()
  workflowCode?: string;

  @ApiProperty({
    description: 'Workflow ID (UUID) - alternative to workflowCode',
    example: '550e8400-e29b-41d4-a716-446655440000',
    required: false,
  })
  @IsOptional()
  @IsUUID(undefined, { message: 'workflowId must be a UUID' })
  workflowId?: string;

  @ApiProperty({
    description: 'Type of license request',
    enum: RequestType,
    example: RequestType.NEW_LICENSE,
    required: false,
  })
  @IsEnum(RequestType)
  @IsOptional()
  requestType?: RequestType;

  @ApiProperty({
    description: 'Applicant name (required)',
    example: 'John Doe',
  })
  @IsString({ message: 'applicantName must be a string' })
  @MinLength(2, { message: 'applicantName must be at least 2 characters' })
  applicantName: string;

  @ApiProperty({
    description: 'Applicant phone number',
    example: '+91-9876543210',
    required: false,
  })
  @IsOptional()
  @IsString()
  @Matches(/^\+?[0-9\-\(\) ]+$/, {
    message: 'applicantPhone must be a valid phone number',
  })
  applicantPhone?: string;

  @ApiProperty({
    description: 'Business name',
    example: 'ABC Restaurant',
    required: false,
  })
  @IsOptional()
  @IsString()
  businessName?: string;

  @ApiProperty({
    description: 'Additional metadata for the request',
    type: Object,
    example: { property: 'value' },
    required: false,
  })
  @IsObject()
  @IsOptional()
  metadata?: Record<string, any>;

  @ApiProperty({
    description: 'Optional blockchain token ID',
    required: false,
    example: 12345,
  })
  @IsOptional()
  tokenId?: number;
}
