'use client';
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var lit = require('lit');
var decorators_js = require('lit/decorators.js');
var ref_js = require('lit/directives/ref.js');
var sgdsCloseButton = require('../CloseButton/sgds-close-button.cjs.js');
var sgdsButton = require('../Button/sgds-button.cjs.js');
var fileUpload = require('./file-upload.cjs.js');
var formControlElement = require('../../base/form-control-element.cjs.js');
var validatorMixin = require('../../utils/validatorMixin.cjs.js');
var watch = require('../../utils/watch.cjs.js');
var sgdsIcon = require('../Icon/sgds-icon.cjs.js');

/**
 * @summary Allows users to upload files of various sizes and formats
 *
 * @slot default - Label for file upload button
 *
 * @event sgds-files-selected - Emitted when files are selected for uploading. Access the selected files with event.target.detail
 */
class SgdsFileUpload extends validatorMixin.SgdsFormValidatorMixin(formControlElement["default"]) {
    constructor() {
        super(...arguments);
        /** Allows multiple files to be listed for uploading */
        this.multiple = false;
        /** Specify the acceptable file type  */
        this.accept = "";
        /** Allows invalidFeedback, invalid and valid styles to be visible with the input */
        this.hasFeedback = false;
        /** Makes the input as a required field. */
        this.required = false;
        this.selectedFiles = [];
        this.inputRef = ref_js.createRef();
    }
    /**
     * Checks for validity. Under the hood, HTMLFormElement's reportValidity method calls this method to check for component's validity state
     * Note that the native error popup is prevented for SGDS form components by default. Instead the validation message shows up in the feedback container of SgdsInput
     */
    reportValidity() {
        return this._mixinReportValidity();
    }
    /**
     * Checks for validity without any native error popup message
     */
    checkValidity() {
        return this._mixinCheckValidity();
    }
    /**
     * Returns the ValidityState object
     */
    get validity() {
        return this._mixinGetValidity();
    }
    /**
     * Returns the validation message based on the ValidityState
     */
    get validationMessage() {
        return this._mixinGetValidationMessage();
    }
    /**
     * Returns files selected for upload
     */
    get files() {
        return this.selectedFiles;
    }
    _setFileList(files) {
        this.emit("sgds-files-selected", { detail: files });
    }
    _handleClick(event) {
        event.preventDefault();
        if (!this.disabled) {
            // Get a reference to the input element using the inputRef
            const inputElement = this.inputRef.value;
            // Do something with the input element
            inputElement.click();
        }
    }
    _handleChange(event) {
        const inputElement = event.target;
        const files = inputElement.files;
        if (files.length > 0) {
            this.selectedFiles = Array.from(files);
        }
        // Trigger a re-render of the component to update the list of selected files
        this._setFileList(files);
        this.requestUpdate();
        super._mixinHandleChange(event);
    }
    _removeFileHandler(index) {
        const inputElement = this.inputRef.value;
        const attachments = inputElement.files;
        const fileBuffer = new DataTransfer();
        for (let i = 0; i < attachments.length; i++) {
            if (index !== i)
                fileBuffer.items.add(attachments[i]);
        }
        // Assign buffer to file input
        inputElement.files = fileBuffer.files;
        // Re-populate selected files to the lists
        this._setFileList(fileBuffer.files);
        this.selectedFiles = Array.from(fileBuffer.files);
        // Trigger a re-render of the component to update the list of selected files
        this.requestUpdate();
        this._mixinValidate(this.input);
    }
    _clearAllFiles() {
        const inputElement = this.inputRef.value;
        const fileBuffer = new DataTransfer();
        inputElement.files = fileBuffer.files;
        this._setFileList(fileBuffer.files);
        this.selectedFiles = Array.from(fileBuffer.files);
    }
    /**
     * fileupload requries a custom _mixinResetFormControl for clearing files
     */
    _mixinResetFormControl() {
        this._clearAllFiles();
        this._mixinResetValidity(this.input);
    }
    _handleDisabledChange() {
        // Disabled form controls are always valid, so we need to recheck validity when the state changes
        this.setInvalid(false);
    }
    _renderLabel() {
        const labelTemplate = lit.html `
      <label for=${this._controlId} id=${this._labelId} class="form-label"> ${this.label} </label>
    `;
        return this.label && labelTemplate;
    }
    _renderHintText() {
        const hintTextTemplate = lit.html ` <div id="${this._controlId}Help" class="form-text">${this.hintText}</div> `;
        return this.hintText && hintTextTemplate;
    }
    _renderFeedback() {
        return lit.html `
      <div class="invalid-feedback-container">
        <sgds-icon name="exclamation-circle-fill" size="md"></sgds-icon>
        <div id="${this._controlId}-invalid" class="invalid-feedback">
          ${this.invalidFeedback ? this.invalidFeedback : this.input.validationMessage}
        </div>
      </div>
    `;
    }
    render() {
        const getCheckedIcon = () => {
            return lit.html `<sgds-icon name="check-circle-fill" class="${this.invalid ? "invalid" : "valid"}"></sgds-icon>`;
        };
        const listItems = this.selectedFiles.map((file, index) => lit.html `
        <li key=${index} class="file-upload-list-item">
          ${getCheckedIcon()}
          <span class="filename">${file.name}</span>
          <sgds-close-button
            aria-label="remove the file"
            @click=${() => this._removeFileHandler(index)}
          ></sgds-close-button>
        </li>
      `);
        return lit.html `
      <div class="file-upload">
        <input
          ${ref_js.ref(this.inputRef)}
          type="file"
          @change=${this._handleChange}
          ?multiple=${this.multiple}
          accept=${this.accept}
          id=${this._controlId}
          ?required=${this.required}
          ?disabled=${this.disabled}
        />
        <div class="file-upload-container">
          ${this._renderLabel()}
          <sgds-button variant="outline" ?disabled=${this.disabled} @click=${this._handleClick}>
            <label for=${this._controlId}><slot></slot></label>
            <sgds-icon slot="rightIcon" name="upload"></sgds-icon>
          </sgds-button>
          ${this.hasFeedback && this.invalid ? this._renderFeedback() : this._renderHintText()}
        </div>
        <ul class="file-upload-list">
          ${listItems}
        </ul>
      </div>
    `;
    }
}
SgdsFileUpload.styles = [...formControlElement["default"].styles, fileUpload["default"]];
/**@internal */
SgdsFileUpload.dependencies = {
    "sgds-button": sgdsButton.SgdsButton,
    "sgds-close-button": sgdsCloseButton.SgdsCloseButton,
    "sgds-icon": sgdsIcon.SgdsIcon
};
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsFileUpload.prototype, "multiple", void 0);
tslib.__decorate([
    decorators_js.property({ type: String, reflect: true })
], SgdsFileUpload.prototype, "accept", void 0);
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsFileUpload.prototype, "hasFeedback", void 0);
tslib.__decorate([
    decorators_js.property({ type: String, reflect: true })
], SgdsFileUpload.prototype, "invalidFeedback", void 0);
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsFileUpload.prototype, "required", void 0);
tslib.__decorate([
    decorators_js.state()
], SgdsFileUpload.prototype, "selectedFiles", void 0);
tslib.__decorate([
    watch.watch("disabled", { waitUntilFirstUpdate: true })
], SgdsFileUpload.prototype, "_handleDisabledChange", null);

exports.SgdsFileUpload = SgdsFileUpload;
exports["default"] = SgdsFileUpload;
//# sourceMappingURL=sgds-file-upload.cjs.js.map
