var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { h } from '@stencil/core';
import { MapToComponentField, VegaSlimmer } from 'vega-slimmer/core';
import { VegaInternalIconManager } from '../../../../helpers/icon/internal-icon-manager';
import arrowUpFromLine from '../../../../global/icons/arrow-up-from-line';
import { DomNodeSubjectObserverFactory } from '../../../../helpers/change-manager/subject/dom-node-subject/dom-node-subject-observer-factory';
import { VegaClick } from '../../../../helpers/event-manager/event-id/vega-event-id';
import { generateUUID } from '../../../../utils/misc';
import { createEnterKeyHandlerToTriggerClick } from '../../../../utils/accessibility';
/* rendering a file uploader with options for drag and drop or button upload functionality. */
export class VegaFileUploaderContainerRenderer extends VegaSlimmer {
  constructor() {
    super(...arguments);
    /**
     * An event handler function that is triggered when the drop area is clicked
     *
     * @param {MouseEvent} e click event object
     */
    this.handleDropAreaClick = (e) => {
      e.stopPropagation();
      if (!this.shouldDisableUploadButton()) {
        this.triggerFileInputClick();
      }
    };
    /**
     * Trigger a click event on the native input element.
     */
    this.triggerFileInputClick = () => {
      this.inputElementRef.click();
    };
    /**
     * An event handler function that is triggered when the input file is changed
     *
     * @param {MouseEvent} e change event object
     */
    this.inputChangeHandler = (e) => {
      e.stopPropagation();
      const files = this.getVegaFilesFromFileList(e.target.files);
      this.selectFileChangeEventEmitHandler(this.filterExceedLimitFiles(files));
      this.inputElementRef.value = '';
    };
    /**
     * an event handler that is triggered when files are dropped onto the file uploader drop area
     *
     * @param {DragEvent} e drag event object
     */
    this.dropHandler = (e) => {
      var _a;
      e.preventDefault();
      if (!this.shouldDisableUploadButton()) {
        const files = this.getVegaFilesFromFileList(this.dropFileFilterController.process((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files));
        this.selectFileChangeEventEmitHandler(this.filterExceedLimitFiles(files));
      }
    };
  }
  /**
   * The function `getUploaderContainerRef` returns a reference to an HTMLDivElement element.
   * @returns {HTMLDivElement} An HTMLDivElement with the reference to the uploader container.
   */
  getUploaderContainerRef() {
    return this.uploaderContainerRef;
  }
  /**
   * generating the HTML structure of the file uploader component
   *
   * @returns {HTMLElement} uploader component upload area element
   */
  render() {
    return (h("div", { class: "vega-file-uploader-container", ref: (ref) => (this.uploaderContainerRef = ref) },
      h("input", { onChange: this.inputChangeHandler, type: "file", multiple: !this.fileLimitController.isSingleMode(), accept: this.accept, style: { display: 'none' }, ref: (node) => (this.inputElementRef = node) }),
      this.variant === 'uploadButton' ? this.renderUploadButton() : this.renderUploadDropArea()));
  }
  /**
   * An upload button element
   *
   * @returns {HTMLElement} html element
   */
  renderUploadButton() {
    return (h("vega-button", { label: "Upload Document", icon: VegaInternalIconManager.getIconKey('arrow-up-from-line'), variant: "secondary", size: "small", disabled: this.shouldDisableUploadButton(), ref: (button) => {
        DomNodeSubjectObserverFactory.addUniqueObserverToNode(button, VegaClick, this.triggerFileInputClick);
      } }));
  }
  /**
   * The uploader file drop area element
   *
   * @returns {HTMLElement} html element
   */
  renderUploadDropArea() {
    return (h("vega-box", { class: {
        'vega-file-upload-area': true,
        'disabled': this.shouldDisableUploadButton(),
      }, padding: "size-24", border: "border-input-field", borderStyle: "dashed", backgroundColor: "bg-tertiary", corners: "rounded-8", tabIndex: 0, onDrop: this.dropHandler, onDragEnter: this.preventDefaultBehavior, onDragOver: this.preventDefaultBehavior, onClick: this.handleDropAreaClick, onKeyDown: createEnterKeyHandlerToTriggerClick() },
      h("vega-flex", { gap: "size-8", alignItems: "center", justifyContent: "center" },
        h("vega-icon", { color: "text-link", icon: VegaInternalIconManager.getIconKey('arrow-up-from-line') }),
        h("vega-font", { color: "text-link", variant: "font-btn-label" }, this.translationSlimmer.t('Select or drop your file here')))));
  }
  /**
   * Used to prevent the default behavior of the browser when a drag event occurs, such as preventing the browser from opening the file when it is dropped onto the page.
   *
   * @param {DragEvent} e drag event object
   */
  preventDefaultBehavior(e) {
    e.preventDefault();
  }
  /**
   * emits a custom event with selected files and updates the value if the event is not prevented.
   *
   * @param {VegaFileUploaderFile[]} files - The `files` parameter in the `selectFileChangeEventEmitHandler` method is an array of `VegaFileUploaderFile` objects.
   */
  selectFileChangeEventEmitHandler(files) {
    if (files && files.length) {
      const e = this.selectFileChangeEventEmitter.emit(files);
      if (!e.defaultPrevented) {
        this.vegaFileUploaderValueController.setValue(this.value && this.value.length
          ? new Array().concat(this.value, files)
          : files);
      }
    }
  }
  /**
   * extracting the files from a file list object. It first initializes an empty array `result` to store the extracted files
   *
   * @param {FileList|File[]|null} fileList file list object
   * @returns {VegaFileUploaderFile[]} the vega file array
   */
  getVegaFilesFromFileList(fileList) {
    const result = [];
    if (fileList && fileList.length) {
      Array.from(fileList).map((file) => {
        result.push({
          key: generateUUID(),
          name: file.name,
          url: file,
        });
      });
    }
    return result;
  }
  /**
   * Determines if the upload button should be disabled based on the component's state.
   *
   * @returns {boolean} True if the upload button should be disabled, otherwise false.
   */
  shouldDisableUploadButton() {
    return this.disabled || !!(this.value && this.maxCount && this.value.length >= this.maxCount);
  }
  /**
   * Filters the selected files to ensure the total number of files does not exceed the maximum count.
   *
   * @param {VegaFileUploaderFile[]} selectedFiles - The files selected by the user.
   * @returns {VegaFileUploaderFile[]} The filtered list of files that do not exceed the maximum count.
   */
  filterExceedLimitFiles(selectedFiles) {
    const maxCount = Number(this.maxCount);
    if (!isNaN(maxCount) && maxCount && selectedFiles.length) {
      const existFileCount = this.value ? this.value.length : 0;
      const availableFileCount = Math.max(0, maxCount - existFileCount);
      return selectedFiles.slice(0, availableFileCount);
    }
    return selectedFiles;
  }
}
(() => {
  VegaInternalIconManager.register({ 'arrow-up-from-line': arrowUpFromLine });
})();
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "variant", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "accept", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "disabled", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "value", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "selectFileChangeEventEmitter", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "vegaFileUploaderValueController", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "dropFileFilterController", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "translationSlimmer", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "fileLimitController", void 0);
__decorate([
  MapToComponentField()
], VegaFileUploaderContainerRenderer.prototype, "maxCount", void 0);
