import type { JSX } from "solid-js";
import { splitProps } from "solid-js";

export interface ProgressProps extends JSX.HTMLAttributes<HTMLDivElement> {
  /** Current value. Pass null for indeterminate. */
  value?: number | null;
  /** Maximum value. @default 100 */
  max?: number;
  /** Custom label function for aria-valuetext. */
  getValueLabel?: (value: number, max: number) => string;
}

/**
 * Displays the progress of a task. Supports determinate and indeterminate states.
 * Indeterminate when value is null or undefined.
 */
export function Progress(props: ProgressProps): JSX.Element {
  const [local, rest] = splitProps(props, ["value", "max", "getValueLabel"]);

  const max = () => local.max ?? 100;
  const isIndeterminate = () => local.value == null;
  const currentValue = (): number | null => local.value ?? null;

  const percentage = () => {
    const v = currentValue();
    if (v === null) return null;
    return Math.round((v / max()) * 100);
  };

  const valueLabel = (): string | undefined => {
    const v = currentValue();
    if (v === null) return undefined;
    if (local.getValueLabel) return local.getValueLabel(v, max());
    const pct = percentage();
    return pct === null ? undefined : `${pct}%`;
  };

  const dataState = (): string => {
    return isIndeterminate() ? "indeterminate" : "complete";
  };

  const valueNow = (): number | undefined => {
    const v = currentValue();
    return isIndeterminate() || v === null ? undefined : v;
  };

  const dataValue = (): number | undefined => {
    const v = currentValue();
    return isIndeterminate() || v === null ? undefined : v;
  };

  return (
    // biome-ignore lint/a11y/useFocusableInteractive: progressbar is read-only, not interactive
    <div
      role="progressbar"
      aria-valuemin={0}
      aria-valuemax={max()}
      aria-valuenow={valueNow()}
      aria-valuetext={valueLabel()}
      data-state={dataState()}
      data-value={dataValue()}
      data-max={max()}
      {...rest}
    />
  );
}
