import { LitElement, html, nothing } from 'lit';
import { btuCelebrate } from '../../effects/celebrate.js';
import { EventEmitterMixin } from '../../util/EventEmitterMixin.js';
import { l10n } from '../../util/i18n.js';
import { ReadyMixin } from '../../util/ReadyMixin.js';
import { formatFileSize, resolveFileSymbol } from '../../util/upload.js';
import '../icon-button/IconButton.js';
import '../icon/Icon.js';
import '../linear-progress/LinearProgress.js';
const STATUS_CLASS_MAP = {
    pending: 'btu-upload-item-active',
    uploading: 'btu-upload-item-active',
    complete: 'btu-upload-item-complete',
    error: 'btu-upload-item-error',
};
/**
 * Internal upload item sub-component for displaying individual file upload state.
 *
 * This component is not part of the public API — consumers should not create,
 * query, or modify items directly. All interaction goes through `btu-upload` methods.
 *
 * @element btu-upload-item
 *
 * @fires {CustomEvent<{id: string}>} btu-upload-item-remove - Fired when remove button is clicked
 * @fires {CustomEvent<{id: string}>} btu-upload-item-retry - Fired when retry link is clicked
 *
 * @cssprop --upload-item-bg - Item background color (default: white)
 * @cssprop --upload-item-border-color - Item border color (default: gray-200)
 * @cssprop --upload-item-active-border-color - Item active/in-progress border (default: gray-300)
 * @cssprop --upload-item-complete-border-color - Item completed border color (default: primary-500)
 * @cssprop --upload-item-error-bg - Item error background (default: error-25)
 * @cssprop --upload-item-error-border-color - Item error border color (default: error-300)
 */
export default class UploadItem extends EventEmitterMixin(ReadyMixin(LitElement)) {
    constructor() {
        super(...arguments);
        this._state = null;
        this._baseClasses = '';
        this._previousStatus = null;
        this._stopProgressComplete = (e) => e.stopPropagation();
    }
    createRenderRoot() {
        return this;
    }
    connectedCallback() {
        super.connectedCallback();
        const initial = this.className ? this.className.split(' ').filter(Boolean) : [];
        this._baseClasses = [...initial, 'btu-upload-item'].join(' ');
        // Contain the inner progress bar's completion event — consumers listen for btu-upload-file-completed.
        this.addEventListener('btu-linear-progress-complete', this._stopProgressComplete);
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this.removeEventListener('btu-linear-progress-complete', this._stopProgressComplete);
    }
    /** @internal Called by Upload to push file state */
    _configure(state) {
        if (this._state === state)
            return;
        this._state = state;
        this.requestUpdate();
    }
    willUpdate() {
        if (!this._state)
            return;
        const nextStatus = this._state.status;
        this.className = `${this._baseClasses} ${STATUS_CLASS_MAP[nextStatus]}`;
        if (this._previousStatus !== 'complete' && nextStatus === 'complete') {
            this._scheduleCelebrate();
        }
        this._previousStatus = nextStatus;
    }
    _scheduleCelebrate() {
        void this.updateComplete.then(() => {
            const progressEl = this.querySelector('btu-linear-progress');
            if (!progressEl)
                return;
            const rect = progressEl.getBoundingClientRect();
            if (rect.width === 0 && rect.height === 0)
                return;
            btuCelebrate({
                position: { x: rect.right, y: rect.top + rect.height / 2 },
                size: 120,
                duration: 1200,
            });
        });
    }
    _handleRemove() {
        if (!this._state)
            return;
        // Internal-only signal to the parent btu-upload. Kept off CustomEventMap so
        // it doesn't appear in the public typed API; parent calls stopPropagation
        // to contain it. Do not rename without updating Upload.firstUpdated.
        this.dispatchEvent(new CustomEvent('btu-upload-item-remove', { detail: { id: this._state.id }, bubbles: true, composed: true }));
    }
    _handleRetry() {
        if (!this._state)
            return;
        this.dispatchEvent(new CustomEvent('btu-upload-item-retry', { detail: { id: this._state.id }, bubbles: true, composed: true }));
    }
    render() {
        if (!this._state)
            return nothing;
        const state = this._state;
        const { file, status, progress, symbol } = state;
        const name = file.name;
        const resolvedSymbol = symbol || resolveFileSymbol(file.type);
        const formattedSize = formatFileSize(file.size);
        const isError = status === 'error';
        const isComplete = status === 'complete';
        const displayProgress = isComplete ? 100 : progress;
        const trackColor = isComplete ? 'gray' : 'primary';
        const errorMessage = status === 'error' ? state.errorMessage : '';
        const cancelLabelText = l10n('upload', 'cancelFile', 'Cancel upload for ___', [name]);
        const cancelTooltip = l10n('upload', 'itemCancelTooltip', 'Cancel');
        const retryLabelText = l10n('upload', 'retryFile', 'Retry upload for ___', [name]);
        return html `
      <btu-icon
        class="${isError ? 'btu-upload-item-icon-error' : ''} btu-upload-item-icon"
        symbol="${resolvedSymbol}"
        size="md"
        emphasize
      ></btu-icon>
      <div class="btu-upload-item-info">
        ${isError
            ? html `
              <span class="btu-upload-item-error-text"
                >${errorMessage || l10n('upload', 'itemError', 'Upload failed')}</span
              >
              <span class="btu-upload-item-error-filename">${name}</span>
              <button
                type="button"
                class="btu-upload-item-retry"
                aria-label="${retryLabelText}"
                @click="${this._handleRetry}"
              >
                ${l10n('upload', 'itemRetry', 'Try again')}
              </button>
            `
            : html `
              <span class="btu-upload-item-name">${name}</span>
              <span class="btu-upload-item-size">${formattedSize}</span>
              <div class="btu-upload-item-progress">
                <btu-linear-progress
                  progress="${displayProgress}"
                  color="primary"
                  thickness="${8}"
                  aria-label="${displayProgress}%"
                  .initialAnimation="${false}"
                  style="--track-color: oklch(var(--btu-theme-${trackColor}-100))"
                ></btu-linear-progress>
                <span class="btu-upload-item-percent">${displayProgress}%</span>
              </div>
            `}
      </div>
      ${isComplete
            ? html `<btu-icon
            class="btu-upload-item-check"
            symbol="check"
            size="sm"
            emphasize="pulse"
            aria-hidden="true"
          ></btu-icon>`
            : html `<btu-icon-button
            class="btu-upload-item-remove"
            symbol="x-circle"
            type="secondary-clear"
            size="sm"
            destructive
            tooltip="${cancelTooltip}"
            aria-label="${cancelLabelText}"
            @btu-icon-button-click="${this._handleRemove}"
          ></btu-icon-button>`}
    `;
    }
}
if (!customElements.get('btu-upload-item')) {
    customElements.define('btu-upload-item', UploadItem);
}
//# sourceMappingURL=UploadItem.js.map