import { ValidationArguments, ValidationOptions, registerDecorator } from 'class-validator';

/**
 * Rejects the decorated property when a related field is present (not null/undefined).
 * All other validators on the property still run normally — this does NOT interfere with them.
 *
 * @param relatedField - The field whose presence triggers the rejection
 * @param validationOptions - Optional class-validator options (e.g. custom message)
 *
 * @example
 * // Reject `search` when `cursor` is provided
 * class ListUsersVC extends MandatoryCursorPaginableVC {
 *     @ForbiddenWithField('cursor')
 *     @IsOptional()
 *     @IsString()
 *     search?: string;
 * }
 */
export function ForbiddenWithField(relatedField: string, validationOptions?: ValidationOptions) {
    return function (object: object, propertyName: string) {
        registerDecorator({
            constraints: [relatedField],
            name: 'forbiddenWithField',
            options: { message: `${propertyName} must not be provided when ${relatedField} is present`, ...validationOptions },
            propertyName,
            target: object.constructor,
            validator: {
                validate(value: unknown, args: ValidationArguments) {
                    const [field] = args.constraints as [string];
                    const relatedValue = (args.object as Record<string, unknown>)[field];
                    if (relatedValue == null) return true;
                    return value === undefined || value === null;
                },
            },
        });
    };
}
