import {
  registerDecorator,
  ValidationOptions,
  ValidationArguments,
} from 'class-validator';
import { Buffer } from 'buffer';
import { imageSize } from 'image-size';

interface Base64ImageOptions {
  mimeTypes?: string[]; // ['image/jpeg', 'image/png']
  maxSizeInBytes?: number; // e.g. 2 * 1024 * 1024
  maxWidth?: number;
  maxHeight?: number;
  allowNull?: boolean; // <-- thêm tùy chọn này
}

export function IsValidBase64Image(
  options: Base64ImageOptions = {},
  validationOptions?: ValidationOptions,
) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: 'isValidBase64Image',
      target: object.constructor,
      propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, _args: ValidationArguments): boolean {
          // Cho phép null nếu được cấu hình
          if (value === null || value === undefined) {
            return !!options.allowNull;
          }

          if (typeof value !== 'string') return false;

          const matches = value.match(/^data:(.+);base64,(.*)$/);
          if (!matches) return false;

          const mimeType = matches[1];
          const base64Data = matches[2];

          // MIME type check
          if (options.mimeTypes && !options.mimeTypes.includes(mimeType)) {
            return false;
          }

          let buffer: Buffer;
          try {
            buffer = Buffer.from(base64Data, 'base64');
          } catch {
            return false;
          }

          // Size check
          if (
            options.maxSizeInBytes &&
            buffer.length > options.maxSizeInBytes
          ) {
            return false;
          }

          // Image dimension check
          try {
            const dimensions = imageSize(buffer);
            if (
              (options.maxWidth && dimensions.width! > options.maxWidth) ||
              (options.maxHeight && dimensions.height! > options.maxHeight)
            ) {
              return false;
            }
          } catch {
            return false;
          }

          return true;
        },

        defaultMessage(args: ValidationArguments) {
          return `${args.property} must be a valid base64 encoded image with allowed mime types, size, and dimensions.`;
        },
      },
    });
  };
}
