/**
 *
 * FileUpload is an advanced uploader with dragdrop support, multi file uploads, auto uploading, progress tracking and validations.
 *
 * [Live Demo](https://www.TSVue.org/fileupload/)
 *
 * @module fileupload
 *
 */
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';

export type InputErrorCodes = 'FILE_SIZE_TOO_LARGE';

/**
 * Defines valid properties in FileUpload component.
 */
export type FileUploadProps = {
  /**
   * Pattern to restrict the allowed file types such as 'image/*'.
   */
  accept?: string | undefined;
  /**
   * Disables the upload functionality.
   * @defaultValue false
   */
  disabled?: boolean | undefined;
  /**
   * Maximum file size allowed in bytes.
   */
  maxFileSize?: number | undefined;
  /**
   * Message of the invalid fize size.
   * - Use {0} to get the file's name
   * - Use {1} to get the max file size
   * - Use {2} to get the accepted file types from props.accept
   * - Use {2.1} to get the accepted file types from props.fileExtensions
   * @defaultValue {0}: Invalid file size, file size should be smaller than {1}.
   */
  invalidFileSizeMessage?: string | undefined;
  /**
   * Message of the invalid fize type.
   * - Use {0} to get the file's name
   * - Use {1} to get the max file size
   * - Use {2} to get the accepted file types
   * - Use {2.1} to get the accepted file types from props.fileExtensions
   * @defaultValue '{0}: Invalid file type, allowed file types: {2}'
   */
  invalidFileTypeMessage?: string | undefined;
  /**
   * Label of the file upload.
   * @defaultValue 'Upload File'
   */
  label?: string | undefined;
  /**
   * Whether to use an upload button.
   * @defaultValue true
   */
  withUpload?: boolean | undefined;
  /**
   * Label of the upload button.
   * @defaultValue 'Upload'.
   */
  uploadLabel?: string | undefined;
  /**
   * Placeholder of the file upload.
   * @defaultValue 'Select File'
   */
  placeholder?: string | undefined;
  /**
   * File extensions to display the accepted extensions.
   */
  fileExtensions?: string | undefined;
  /**
   * The note about the requirements of file for being uploaded.
   *
   * Placed at the bottom right of input.
   */
  fileRequirements?: string | undefined;
  /**
   * The function to be called after the upload button is clicked. (Must be used when withUpload is true)
   */
  uploadFunction?: (files: File[]) => Promise<void>;
  /**
   * Whether the input should be validated with vee-validator or not.
   * If you use this component within form input, you need to set this props as true.
   */
  useValidator?: boolean;
  /**
   * This prop is required if you use this component in a form input.
   * Specify the unique field name, match with your needs for API request.
   *
   * @default 'fileUpload'
   */
  fieldName?: string;
  /**
   * Whether this input field is required or not.
   */
  mandatory?: boolean;
  /**
   * Wether show toast error message on invalid file input
   *
   * @default true;
   */
  useErrorToast?: boolean;
  /**
   * Wether show validator message on invalid file input
   */
  showValidatorMessage?: boolean;
  /**
   * Wether show validator message on invalid file input
   */
  validatorMessage?: boolean;
};

export type FileUploadEmits = {
  /**
   * Callback to invoke when files are selected.
   * @param {FileUploadSelectEvent} event - Custom select event.
   */
  'select': [event: FileUploadSelectEvent];
  /**
   * Callback to invoke before file upload begins to customize the request such as post parameters before the files.
   * @param {FileUploadBeforeUploadEvent} event - Custom before upload event.
   */
  'before-upload': [event: FileUploadBeforeUploadEvent];
  /**
   * Callback to invoke when files are being uploaded.
   * @param {FileUploadProgressEvent} event - Custom progress event.
   */
  'progress': [event: FileUploadProgressEvent];
  /**
   * Callback to invoke when file upload is complete.
   * @param {FileUploadUploadEvent} event - Custom upload event.
   */
  'upload': [event: FileUploadUploadEvent];
  /**
   * Callback to invoke to implement a custom upload.
   * @param {FileUploadUploaderEvent} event - Custom uploader event.
   */
  'uploader': [event: FileUploadUploaderEvent];
  /**
   * Callback to invoke if file upload fails.
   * @param {FileUploadErrorEvent} event - Custom error event.
   */
  'error': [event: FileUploadErrorEvent | InputErrorCodes];
  /**
   * Callback to invoke before file send begins to customize the request such as adding headers.
   * @param {FileUploadBeforeSendEvent} event - Custom before send event.
   */
  'before-send': [event: FileUploadBeforeSendEvent];
  /**
   * Callback to invoke when files in queue are removed without uploading.
   */
  'clear': [];
  /**
   * Callback to invoke when a singe file is removed from the list.
   * @param {FileUploadRemoveEvent} event - Custom remove event.
   */
  'remove': [event: FileUploadRemoveEvent];
  /**
   * Callback to invoke when a single uploaded file is removed from the uploaded file list.
   * @param {FileUploadRemoveUploadedFile} event - Custom uploaded file remove event.
   */
  'removeUploadedFile': [event: FileUploadRemoveUploadedFile];
};

/**
 * **TSVue - FileUpload**
 *
 * _FileUpload is an advanced uploader with dragdrop support, multi file uploads, auto uploading, progress tracking and validations._
 *
 * --- ---
 * ![TSVue](https://ik.imagekit.io/kurniadev/TS-HEAD-BLACK.png)
 *
 * @group Component
 *
 */
declare class FileUpload extends ClassComponent<
  FileUploadProps,
  null,
  FileUploadEmits
> {}

declare module '@vue/runtime-core' {
  interface GlobalComponents {
    FileUpload: GlobalComponentConstructor<FileUpload>;
  }
}

export default FileUpload;
