import ora from "ora";
import cliProgress from "cli-progress";
import chalk from "chalk";
class TuiReporter {
  states = /* @__PURE__ */ new Map();
  stream;
  constructor(opts = {}) {
    this.stream = opts.useStdout === false ? process.stderr : process.stdout;
  }
  start(id, label, opts) {
    const spinner = ora({ text: label, stream: this.stream }).start();
    this.states.set(id, { spinner, label, totalBytes: opts?.totalBytes });
  }
  update(id, text) {
    const s = this.states.get(id);
    if (!s) return;
    s.spinner.text = text;
  }
  progress(id, fraction) {
    const s = this.states.get(id);
    if (!s) return;
    const clamped = Math.max(0, Math.min(1, fraction));
    if (s.totalBytes && s.totalBytes > 0) {
      if (!s.bar) {
        s.spinner.stop();
        s.bar = new cliProgress.SingleBar(
          {
            format: `  ${chalk.cyan("{bar}")} {percentage}% | ${s.label}`,
            barCompleteChar: "\u2588",
            barIncompleteChar: "\u2591",
            hideCursor: true,
            stream: this.stream
          },
          cliProgress.Presets.shades_classic
        );
        s.bar.start(s.totalBytes, 0);
      }
      s.bar.update(Math.round(clamped * s.totalBytes));
    } else {
      const pct = Math.round(clamped * 100);
      s.spinner.text = `${s.label} (${pct}%)`;
    }
  }
  success(id, detail) {
    const s = this.states.get(id);
    if (!s) return;
    const msg = detail ? `${s.label} \u2014 ${chalk.gray(detail)}` : s.label;
    if (s.bar) {
      s.bar.update(s.totalBytes ?? 0);
      s.bar.stop();
      this.stream.write(`${chalk.green("\u2713")} ${msg}
`);
    } else {
      s.spinner.succeed(msg);
    }
    this.states.delete(id);
  }
  fail(id, error) {
    const s = this.states.get(id);
    if (!s) return;
    const msg = `${s.label} \u2014 ${chalk.red(error)}`;
    if (s.bar) {
      s.bar.stop();
      this.stream.write(`${chalk.red("\u2717")} ${msg}
`);
    } else {
      s.spinner.fail(msg);
    }
    this.states.delete(id);
  }
  note(text) {
    process.stdout.write(`${text}
`);
  }
  finish() {
    for (const s of this.states.values()) {
      if (s.bar) {
        try {
          s.bar.stop();
        } catch {
        }
      } else {
        try {
          s.spinner.stop();
        } catch {
        }
      }
    }
    this.states.clear();
  }
}
export {
  TuiReporter
};
//# sourceMappingURL=tui-reporter.js.map