// Shared UI helpers: toasts and a reusable progress panel.

import { h, fmtElapsed } from "./dom";

export function toast(message: string, kind: "ok" | "err" | "" = "") {
  const host = document.getElementById("toasts")!;
  const el = h("div", { class: `toast ${kind}` },
    h("span", {}, kind === "ok" ? "✓" : kind === "err" ? "⚠" : "•"),
    h("span", {}, message),
  );
  host.append(el);
  setTimeout(() => {
    el.style.transition = "opacity .25s, transform .25s";
    el.style.opacity = "0";
    el.style.transform = "translateY(8px)";
    setTimeout(() => el.remove(), 260);
  }, kind === "err" ? 6000 : 3200);
}

/** A progress bar + status/timing line + collapsible log, returned as one unit. */
export function makeProgress() {
  const fill = h("i");
  const bar = h("div", { class: "bar" }, fill);
  const status = h("span", { class: "status" }, "Ready");
  const timing = h("span", { class: "timing" });
  const log = h("div", { class: "log" });
  const root = h("div", { class: "progress-wrap" },
    bar,
    h("div", { class: "progress-meta" }, status, timing),
    log,
  );

  return {
    root,
    reset() {
      bar.classList.remove("indeterminate");
      fill.style.width = "0%";
      status.textContent = "Ready";
      timing.textContent = "";
      log.textContent = "";
    },
    indeterminate(on: boolean, text?: string) {
      bar.classList.toggle("indeterminate", on);
      if (on) fill.style.width = "35%";
      if (text) status.textContent = text;
    },
    set(pct: number, statusText: string, opts?: { elapsed?: number; eta?: number; speed?: number }) {
      bar.classList.remove("indeterminate");
      fill.style.width = `${Math.round(pct * 100)}%`;
      status.textContent = statusText;
      if (opts) {
        const bits: string[] = [];
        if (opts.elapsed != null) bits.push(`Elapsed ${fmtElapsed(opts.elapsed)}`);
        if (opts.eta != null && opts.eta > 0) bits.push(`ETA ${fmtElapsed(opts.eta)}`);
        if (opts.speed != null && opts.speed > 0) bits.push(`${opts.speed.toFixed(1)}×`);
        timing.textContent = bits.join("  ·  ");
      }
    },
    setTiming(text: string) { timing.textContent = text; },
    appendLog(line: string) {
      log.textContent += (log.textContent ? "\n" : "") + line;
      log.scrollTop = log.scrollHeight;
    },
  };
}

export type Progress = ReturnType<typeof makeProgress>;
