/**
 * Non-side-effect class export for `<progress-ui>`.
 *
 * Importing this file gives you the class(es) without auto-registering the tag.
 * Useful for test isolation, subclassing with tag-name override, or selective
 * composition.
 *
 * The auto-register path stays at `@adia-ai/web-components/components/progress`
 * (which imports this file + calls `defineIfFree()`).
 *
 * @see ../../USAGE.md#registration--auto-vs-explicit
 */

/**
 * <progress-ui value="60"></progress-ui>
 * <progress-ui variant="spinner"></progress-ui>
 * <progress-ui></progress-ui>              <!-- indeterminate bar -->
 *
 * Progress indicator. Bar (default) or spinner variant.
 * value null (absent) = indeterminate, 0-100 = determinate.
 * (Legacy `value="-1"` is still treated as indeterminate for back-compat.)
 */

import { UIElement } from '../../core/element.js';

export class UIProgress extends UIElement {
  static properties = {
    value:   { type: Number, default: null,  reflect: true },
    variant: { type: String, default: 'bar', reflect: true },
  };

  static template = () => null;

  #track = null;
  #fill = null;

  connected() {
    this.setAttribute('role', 'progressbar');
    this.setAttribute('aria-valuemin', '0');
    this.setAttribute('aria-valuemax', '100');

    if (this.variant === 'bar') {
      this.#track = document.createElement('div');
      this.#track.setAttribute('slot', 'track');
      this.#fill = document.createElement('div');
      this.#fill.setAttribute('slot', 'fill');
      this.#track.appendChild(this.#fill);
      this.appendChild(this.#track);
    }
  }

  render() {
    const indeterminate = this.value == null || this.value < 0;
    const clamped = Math.max(0, Math.min(100, this.value));

    this.setAttribute('aria-busy', String(indeterminate));

    if (indeterminate) {
      this.removeAttribute('aria-valuenow');
    } else {
      this.setAttribute('aria-valuenow', String(clamped));
    }

    if (this.#fill) {
      this.#fill.style.width = indeterminate ? '100%' : `${clamped}%`;
    }
  }

  disconnected() {
    this.#track?.remove();
    this.#track = null;
    this.#fill = null;
  }
}
