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

const VND_MIN = 1;
const VND_MAX = 100_000_000_000; // 100 tỷ VND

export interface IsVNDOptions {
  min?: number;
  max?: number;
}

@ValidatorConstraint({ name: 'isVND', async: false })
export class IsVNDConstraint implements ValidatorConstraintInterface {
  validate(value: unknown, args: ValidationArguments): boolean {
    const opts = (args.constraints[0] as IsVNDOptions) ?? {};
    const min = opts.min ?? VND_MIN;
    const max = opts.max ?? VND_MAX;

    if (typeof value === 'bigint') {
      return value >= BigInt(min) && value <= BigInt(max);
    }
    if (typeof value === 'number') {
      return Number.isInteger(value) && value >= min && value <= max;
    }
    return false;
  }

  defaultMessage(args: ValidationArguments): string {
    const opts = (args.constraints[0] as IsVNDOptions) ?? {};
    const min = opts.min ?? VND_MIN;
    const max = opts.max ?? VND_MAX;
    return `${args.property} phải là số tiền VND hợp lệ (${min.toLocaleString('vi-VN')} - ${max.toLocaleString('vi-VN')} VND)`;
  }
}

export function IsVND(options?: IsVNDOptions, validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName,
      options: validationOptions,
      constraints: [options ?? {}],
      validator: IsVNDConstraint,
    });
  };
}
