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 { UmbFileDropzoneItemStatus } from '../../constants.js';
import { UmbDropzoneManager } from '../../dropzone-manager.class.js';
import { UmbDropzoneChangeEvent } from '../../dropzone-change.event.js';
import { UmbDropzoneSubmittedEvent } from '../../dropzone-submitted.event.js';
import { css, customElement, html, ifDefined, nothing, property, query, repeat, state, when, } from '../../../../../external/lit/index.js';
import { UmbLitElement } from '../../../../core/lit-element/index.js';
import { UmbTextStyles } from '../../../../core/style/index.js';
import { formatBytes } from '../../../../core/utils/index.js';
import { UmbFormControlMixin } from '../../../../core/validation/index.js';
/**
 * A dropzone for uploading files and folders.
 * The files will be uploaded to the server as temporary files and can be used in the backoffice.
 * @element umb-input-dropzone
 * @fires ProgressEvent When the progress of the upload changes.
 * @fires UmbDropzoneChangeEvent When the upload is complete.
 * @fires UmbDropzoneSubmittedEvent When the upload is submitted.
 * @slot - The default slot.
 * @slot text - A text shown above the dropzone graphic.
 */
let UmbInputDropzoneElement = class UmbInputDropzoneElement extends UmbFormControlMixin(UmbLitElement) {
    /**
     * Determines if the dropzone should be disabled.
     * If the dropzone is disabled, it will not accept any uploads.
     * It is considered disabled if the `disabled` property is set or if `multiple` is set to `false` and there is already an upload in progress.
     * @returns {boolean} True if the dropzone should not accept uploads, otherwise false.
     */
    get #isDisabled() {
        return this.disabled || (!this.multiple && this._progressItems.length > 0);
    }
    constructor() {
        super();
        /**
         * Disable folder uploads.
         */
        this.disableFolderUpload = false;
        /**
         * Disables the dropzone.
         * @description The dropzone will not accept any uploads.
         */
        this.disabled = false;
        /**
         * Determines if the dropzone should accept multiple files.
         */
        this.multiple = false;
        /**
         * Style the dropzone with a border.
         * @description This is useful if you want to display the dropzone directly rather than as a part of a separate component.
         */
        this.standalone = false;
        /**
         * The label for the dropzone.
         */
        this.label = 'dropzone';
        this._progressItems = [];
        this._manager = new UmbDropzoneManager(this);
        this._observeProgress();
        this._observeProgressItems();
    }
    _observeProgress() {
        this.observe(this._manager.progress, (progress) => {
            this.dispatchEvent(new ProgressEvent('progress', { loaded: progress.completed, total: progress.total }));
        }, '_observeProgress');
    }
    _observeProgressItems() {
        this.observe(this._manager.progressItems, (progressItems) => {
            this._progressItems = [...progressItems];
            const waiting = this._progressItems.find((item) => item.status === UmbFileDropzoneItemStatus.WAITING);
            if (this._progressItems.length && !waiting) {
                this.value = [...this._progressItems];
                this.dispatchEvent(new UmbDropzoneChangeEvent(this._progressItems));
            }
        }, '_observeProgressItems');
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this._manager.destroy();
    }
    /**
     * Opens the file browse dialog.
     */
    browse() {
        if (this.#isDisabled)
            return;
        this._dropzone?.browse();
    }
    render() {
        return html `
			<slot name="text"></slot>
			<uui-file-dropzone
				id="dropzone"
				label=${this.label}
				accept=${ifDefined(this.accept)}
				?multiple=${this.multiple}
				?disabled=${this.#isDisabled}
				?disallowFolderUpload=${this.disableFolderUpload}
				@change=${this.onUpload}
				@click=${this.#handleBrowse}>
				<slot>
					<uui-button label=${this.localize.term('media_clickToUpload')} @click=${this.#handleBrowse}></uui-button>
				</slot>
			</uui-file-dropzone>
			${this.renderUploader()}
		`;
    }
    renderUploader() {
        if (!this._progressItems?.length)
            return nothing;
        return html `
			<div id="uploader">
				${repeat(this._progressItems, (item) => item.unique, (item) => this.renderPlaceholder(item))}
				<uui-button
					id="uploader-clear"
					compact
					@click=${this.#handleRemove}
					label=${this.localize.term('content_uploadClear')}>
					<uui-icon name="icon-trash"></uui-icon>
					<umb-localize key="content_uploadClear">Clear file(s)</umb-localize>
				</uui-button>
			</div>
		`;
    }
    renderPlaceholder(item) {
        const file = item.temporaryFile?.file;
        return html `
			<div class="placeholder">
				<div class="fileIcon">
					${when(item.status === UmbFileDropzoneItemStatus.COMPLETE, () => html `<umb-icon name="check" color="green"></umb-icon>`)}
					${when(item.status === UmbFileDropzoneItemStatus.ERROR ||
            item.status === UmbFileDropzoneItemStatus.CANCELLED ||
            item.status === UmbFileDropzoneItemStatus.NOT_ALLOWED, () => html `<umb-icon name="wrong" color="red"></umb-icon>`)}
				</div>
				<div class="fileDetails">
					<div class="fileName" title=${file?.name ?? ''}>${file?.name ?? ''}</div>
					<div class="fileSize">
						${formatBytes(file?.size ?? 0, { decimals: 2 })}:
						${this.localize.number(item.progress, { maximumFractionDigits: 0 })}%
					</div>
					${when(item.status === UmbFileDropzoneItemStatus.WAITING, () => html `<div class="progress"><uui-loader-bar progress=${item.progress}></uui-loader-bar></div>`)}
					${when(item.status === UmbFileDropzoneItemStatus.ERROR, () => html `<div class="error">An error occured</div>`)}
					${when(item.status === UmbFileDropzoneItemStatus.CANCELLED, () => html `<div class="error">Cancelled</div>`)}
					${when(item.status === UmbFileDropzoneItemStatus.NOT_ALLOWED, () => html `<div class="error">
								${item.statusMessage ?? this.localize.term('media_disallowedFileType')}.
							</div>`)}
				</div>
				<div class="fileActions">
					${when(item.status === UmbFileDropzoneItemStatus.WAITING, () => html `
							<uui-button
								compact
								@click=${() => this.#handleCancel(item)}
								label=${this.localize.term('general_cancel')}>
								<uui-icon name="icon-remove"></uui-icon>${this.localize.term('general_cancel')}
							</uui-button>
						`)}
				</div>
			</div>
		`;
    }
    async onUpload(e) {
        e.stopImmediatePropagation();
        if (this.#isDisabled)
            return;
        if (!e.detail.files.length && !e.detail.folders.length)
            return;
        const uploadables = this._manager.createTemporaryFiles(e.detail.files);
        this.dispatchEvent(new UmbDropzoneSubmittedEvent(await uploadables));
    }
    #handleBrowse(e) {
        if (!this._dropzone)
            return;
        e.stopImmediatePropagation();
        this._dropzone.browse();
    }
    #handleCancel(item) {
        item.temporaryFile?.abortController?.abort();
    }
    #handleRemove() {
        this._manager.removeAll();
    }
    static { this.styles = [
        UmbTextStyles,
        css `
			:host {
				display: flex;
				flex-direction: column;
				flex-wrap: wrap;
				place-items: center;
				cursor: pointer;
			}

			:host([disabled]) #dropzone {
				opacity: 0.5;
				pointer-events: none;
			}

			:host([standalone]) {
				position: relative;
				display: block;
				inset: 0;
				cursor: pointer;
				border: 1px dashed var(--uui-color-divider-emphasis);
				border-radius: var(--uui-border-radius);
			}

			:host([standalone]:not([disabled]):hover) {
				border-color: var(--uui-color-default-emphasis);
				--uui-color-default: var(--uui-color-default-emphasis);
				color: var(--uui-color-default-emphasis);
			}

			#dropzone {
				width: 100%;
				inset: 0;
				backdrop-filter: opacity(1); /* Removes the built in blur effect */

				&[disabled] {
					opacity: 0.5;
					pointer-events: none;
				}
			}

			#uploader {
				display: flex;
				flex-direction: column;
				flex-wrap: wrap;
				align-items: center;
				gap: var(--uui-size-space-3);

				.placeholder {
					display: grid;
					grid-template-columns: 30px 200px 1fr;
					max-width: fit-content;
					padding: var(--uui-size-space-3);
					border: 1px dashed var(--uui-color-divider-emphasis);
				}

				.fileIcon,
				.fileActions {
					place-self: center center;
				}

				.fileName {
					white-space: nowrap;
					overflow: hidden;
					text-overflow: ellipsis;
					font-size: var(--uui-size-5);
				}

				.fileSize {
					font-size: var(--uui-font-size-small);
					color: var(--uui-color-text-alt);
				}

				.error {
					color: var(--uui-color-danger);
				}
			}
		`,
    ]; }
};
__decorate([
    property({ type: String })
], UmbInputDropzoneElement.prototype, "accept", void 0);
__decorate([
    property({ type: Boolean, attribute: 'disable-folder-upload' })
], UmbInputDropzoneElement.prototype, "disableFolderUpload", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbInputDropzoneElement.prototype, "disabled", void 0);
__decorate([
    property({ type: Boolean })
], UmbInputDropzoneElement.prototype, "multiple", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbInputDropzoneElement.prototype, "standalone", void 0);
__decorate([
    property({ type: String })
], UmbInputDropzoneElement.prototype, "label", void 0);
__decorate([
    query('#dropzone', true)
], UmbInputDropzoneElement.prototype, "_dropzone", void 0);
__decorate([
    state()
], UmbInputDropzoneElement.prototype, "_progressItems", void 0);
UmbInputDropzoneElement = __decorate([
    customElement('umb-input-dropzone')
], UmbInputDropzoneElement);
export { UmbInputDropzoneElement };
