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 { property } from 'lit/decorators.js';
import { announce } from '../util/aria';
/**
 * Mixin that adds common progress indicator properties.
 * Used by progress components like CircularProgress and LinearProgress.
 *
 * @mixin
 *
 * @param Base - The base class to extend
 * @returns Extended class with progress properties
 *
 * @fires {CustomEvent} btu-linear-progress-ready - Fired on btu-linear-progress after first render
 * @fires {CustomEvent} btu-linear-progress-complete - Fired on btu-linear-progress when progress reaches 100
 * @fires {CustomEvent} btu-circular-progress-ready - Fired on btu-circular-progress after first render
 * @fires {CustomEvent} btu-circular-progress-complete - Fired on btu-circular-progress when progress reaches 100
 *
 * @cssprop --progress-color - Progress indicator color (overrides theme color)
 * @cssprop --track-color - Track/background color (overrides default gray-100)
 *
 * @example
 * ```typescript
 * class MyProgress extends ProgressMixin(LitElement) {
 *   // Component now has color, size, thickness, and progress properties
 * }
 * ```
 */
export const ProgressMixin = (Base) => {
    class ProgressMixinClass extends Base {
        constructor() {
            super(...arguments);
            /**
             * Color theme of the progress indicator.
             * Supports: black, white, primary, teal, gray, purple, rose, error, warning, success
             * @attr
             */
            this.color = 'primary';
            this._progress = 0;
            /**
             * Whether to animate progress from 0 to target value when component first becomes visible.
             * @attr initial-animation
             */
            this.initialAnimation = true;
            /**
             * Optional aria-label attribute for screen readers.
             * Describes what the progress indicator represents.
             * @attr aria-label
             */
            this.ariaLabel = null;
            /**
             * Optional aria-labelledby attribute for screen readers.
             * References the ID of an element that labels the progress indicator.
             * @attr aria-labelledby
             */
            this.ariaLabelledBy = null;
            /**
             * Optional aria-valuetext attribute for screen readers.
             * Provides human-readable text alternative for progress value.
             * @attr aria-valuetext
             */
            this.ariaValueText = null;
            this._isAnimationInitialized = false;
            this._hasCompletedAt100 = false;
        }
        /**
         * Progress value for determinate variant. Clamped to 0–100.
         * @attr
         */
        get progress() {
            return this._progress;
        }
        set progress(value) {
            const numValue = isNaN(value) ? 0 : value;
            this._progress = Math.min(Math.max(numValue, 0), 100);
        }
        /**
         * @internal
         * Get the color value with --progress-color custom property override support.
         * Returns a CSS color string that checks for custom property first, then falls back to theme color.
         */
        _getProgressColorValue() {
            // Handle special colors (white, black)
            if (this.color === 'white' || this.color === 'black') {
                return `var(--progress-color, var(--btu-theme-${this.color}))`;
            }
            // Standard theme colors use -600 variant
            return `var(--progress-color, oklch(var(--btu-theme-${this.color}-600)))`;
        }
        /**
         * @internal
         * Get the animated progress value.
         * Returns 0 if initialAnimation is enabled and animation hasn't started yet, otherwise returns actual progress.
         */
        _getAnimatedProgress() {
            if (this.initialAnimation && !this._isAnimationInitialized) {
                return 0;
            }
            return this._progress;
        }
        /**
         * @internal
         * Setup initial animation with IntersectionObserver when component first becomes visible.
         * Should be called from component's firstUpdated() or updated() methods.
         * Safe to call multiple times - will skip if already initialized.
         */
        _setupInitialAnimation() {
            if (!this.initialAnimation || this._isAnimationInitialized) {
                this._isAnimationInitialized = true;
                return;
            }
            this._cleanupInitialAnimation();
            this._intersectionObserver = new IntersectionObserver(entries => {
                entries.forEach(entry => {
                    if (entry.isIntersecting && !this._isAnimationInitialized) {
                        requestAnimationFrame(() => {
                            this._isAnimationInitialized = true;
                            this.requestUpdate();
                        });
                        this._intersectionObserver?.disconnect();
                    }
                });
            }, { threshold: 0.1 });
            this._intersectionObserver.observe(this);
        }
        /**
         * @internal
         * Cleanup intersection observer.
         * Should be called from component's disconnectedCallback() method.
         */
        _cleanupInitialAnimation() {
            this._intersectionObserver?.disconnect();
        }
        // Resolved at runtime so a single mixin can drive both concrete progress components.
        get _hostTag() {
            return this.tagName.toLowerCase();
        }
        /** @internal Emits `btu-<tag>-ready` after first render. */
        firstUpdated(changedProperties) {
            super.firstUpdated(changedProperties);
            this.emit(`${this._hostTag}-ready`);
        }
        /**
         * @internal
         * Track progress completion and emit `btu-<tag>-complete` on the 0→100 edge.
         * Call from the component's updated() method.
         */
        _trackCompletion() {
            if (this._progress === 100 && !this._hasCompletedAt100) {
                this._hasCompletedAt100 = true;
                this.emit(`${this._hostTag}-complete`);
                if (this.completionAnnouncement) {
                    announce(this.completionAnnouncement);
                }
            }
            else if (this._progress < 100 && this._hasCompletedAt100) {
                this._hasCompletedAt100 = false;
            }
        }
    }
    __decorate([
        property({ type: String })
    ], ProgressMixinClass.prototype, "color", void 0);
    __decorate([
        property({ type: Number })
    ], ProgressMixinClass.prototype, "thickness", void 0);
    __decorate([
        property({ type: Number })
    ], ProgressMixinClass.prototype, "progress", null);
    __decorate([
        property({ type: String })
    ], ProgressMixinClass.prototype, "label", void 0);
    __decorate([
        property({ type: Boolean, attribute: 'initial-animation' })
    ], ProgressMixinClass.prototype, "initialAnimation", void 0);
    __decorate([
        property({ type: String, attribute: 'aria-label' })
    ], ProgressMixinClass.prototype, "ariaLabel", void 0);
    __decorate([
        property({ type: String, attribute: 'aria-labelledby' })
    ], ProgressMixinClass.prototype, "ariaLabelledBy", void 0);
    __decorate([
        property({ type: String, attribute: 'aria-valuetext' })
    ], ProgressMixinClass.prototype, "ariaValueText", void 0);
    __decorate([
        property({ type: String, attribute: 'completion-announcement' })
    ], ProgressMixinClass.prototype, "completionAnnouncement", void 0);
    return ProgressMixinClass;
};
//# sourceMappingURL=ProgressMixin.js.map